diff --git a/Directory.Packages.props b/Directory.Packages.props index cf6dbf6b28..e2ea3dc099 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -27,6 +27,7 @@ + diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json index 5b713a52ab..ab5e61a31f 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json @@ -602,9 +602,21 @@ "ProductCount": "Product Count", "Actions": "Actions", "CreateInvoice": "Create Invoice", + "IsVisible": "Visible", + "Menu:Testimonials": "Testimonials", + "TestimonialDeletionConfirmationMessage": "Are you sure you want to delete this testimonial ?", + "FullName": "Full name", + "TestimonialText": "Testimonial text", + "ExperienceYear": "Experience year", + "Position": "Title", + "YearsOfExperience": "Experience year", "AllowedLicenses": "Allowed Licenses", "AllowedModules": "Allowed Modules", "ModuleName": "Module name", - "NonYet": "Non yet" + "NonYet": "Non yet", + "Permission:Testimonials": "Testimonials", + "SelectCompanySizePlaceholder": "Company Size", + "SelectExperienceYearPlaceholder": "Experience year", + "SelectCountryPlaceholder": "Country" } -} +} \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/tr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/tr.json index 0aca0b7333..1ae377a389 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/tr.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/tr.json @@ -443,6 +443,18 @@ "QuotationTemplate.Tax/VAT:": "Vergiler (%{0}) :", "QuotationTemplate.TotalDiscount:": "Toplam İndirim :", "QuotationTemplate.TOTALDUE:": "NET TOPLAM :", - "QuotationTemplate.BankAccount": "Banka hesabı bilgilerimiz {0} adresinde bulunabilir." + "QuotationTemplate.BankAccount": "Banka hesap bilgilerimize {0} adresinden erişebilirsiniz.", + "Menu:Testimonials": "Referanslar", + "IsVisible": "Görünürlük", + "TestimonialDeletionConfirmationMessage": "Bu referansı silmek istediğinize emin misiniz ?", + "FullName": "Ad soyad", + "TestimonialText": "Tecrübe yazısı", + "ExperienceYear": "Sektörel deneyim", + "Position": "Başlık", + "Actions": "İşlemler", + "Permission:Testimonials": "Referanslar", + "SelectCompanySizePlaceholder": "Şirket Büyüklüğü", + "SelectExperienceYearPlaceholder": "Sektörel deneyim", + "SelectCountryPlaceholder": "Ülke" } -} +} \ No newline at end of file diff --git a/framework/Volo.Abp.sln b/framework/Volo.Abp.sln index b46a809403..3373a239de 100644 --- a/framework/Volo.Abp.sln +++ b/framework/Volo.Abp.sln @@ -465,6 +465,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Imaging.SkiaSharp. EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.RemoteServices.Tests", "test\Volo.Abp.RemoteServices.Tests\Volo.Abp.RemoteServices.Tests.csproj", "{DACD4485-61BE-4DE5-ACAE-4FFABC122500}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.AspNetCore.Abstractions", "src\Volo.Abp.AspNetCore.Abstractions\Volo.Abp.AspNetCore.Abstractions.csproj", "{E1051CD0-9262-4869-832D-B951723F4DDE}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -1387,6 +1389,10 @@ Global {DACD4485-61BE-4DE5-ACAE-4FFABC122500}.Debug|Any CPU.Build.0 = Debug|Any CPU {DACD4485-61BE-4DE5-ACAE-4FFABC122500}.Release|Any CPU.ActiveCfg = Release|Any CPU {DACD4485-61BE-4DE5-ACAE-4FFABC122500}.Release|Any CPU.Build.0 = Release|Any CPU + {E1051CD0-9262-4869-832D-B951723F4DDE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E1051CD0-9262-4869-832D-B951723F4DDE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E1051CD0-9262-4869-832D-B951723F4DDE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E1051CD0-9262-4869-832D-B951723F4DDE}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1621,6 +1627,7 @@ Global {198683D0-7DC6-40F2-B81B-8E446E70A9DE} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {DFAF8763-D1D6-4EB4-B459-20E31007FE2F} = {447C8A77-E5F0-4538-8687-7383196D04EA} {DACD4485-61BE-4DE5-ACAE-4FFABC122500} = {447C8A77-E5F0-4538-8687-7383196D04EA} + {E1051CD0-9262-4869-832D-B951723F4DDE} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5} diff --git a/framework/src/Volo.Abp.AspNetCore.Abstractions/FodyWeavers.xml b/framework/src/Volo.Abp.AspNetCore.Abstractions/FodyWeavers.xml new file mode 100644 index 0000000000..1715698ccd --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Abstractions/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Abstractions/FodyWeavers.xsd b/framework/src/Volo.Abp.AspNetCore.Abstractions/FodyWeavers.xsd new file mode 100644 index 0000000000..ffa6fc4b78 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Abstractions/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Abstractions/Volo.Abp.AspNetCore.Abstractions.csproj b/framework/src/Volo.Abp.AspNetCore.Abstractions/Volo.Abp.AspNetCore.Abstractions.csproj new file mode 100644 index 0000000000..c96dbc0c7b --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Abstractions/Volo.Abp.AspNetCore.Abstractions.csproj @@ -0,0 +1,23 @@ + + + + + + + netstandard2.0;netstandard2.1;net8.0 + enable + Nullable + Volo.Abp.AspNetCore.Abstractions + Volo.Abp.AspNetCore.Abstractions + $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; + false + false + false + + + + + + + + diff --git a/framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/AbpAspNetCoreAbstractionsModule.cs b/framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/AbpAspNetCoreAbstractionsModule.cs new file mode 100644 index 0000000000..6a15c5550f --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/AbpAspNetCoreAbstractionsModule.cs @@ -0,0 +1,15 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.AspNetCore.VirtualFileSystem; +using Volo.Abp.AspNetCore.WebClientInfo; +using Volo.Abp.Modularity; + +namespace Volo.Abp.AspNetCore; + +public class AbpAspNetCoreAbstractionsModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddSingleton(); + context.Services.AddSingleton();; + } +} diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Filters/IAbpFilter.cs b/framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/Filters/IAbpFilter.cs similarity index 100% rename from framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Filters/IAbpFilter.cs rename to framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/Filters/IAbpFilter.cs diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/VirtualFileSystem/IWebContentFileProvider.cs b/framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/VirtualFileSystem/IWebContentFileProvider.cs similarity index 100% rename from framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/VirtualFileSystem/IWebContentFileProvider.cs rename to framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/VirtualFileSystem/IWebContentFileProvider.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/VirtualFileSystem/NullWebContentFileProvider.cs b/framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/VirtualFileSystem/NullWebContentFileProvider.cs new file mode 100644 index 0000000000..a690c36062 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/VirtualFileSystem/NullWebContentFileProvider.cs @@ -0,0 +1,22 @@ +using Microsoft.Extensions.FileProviders; +using Microsoft.Extensions.Primitives; + +namespace Volo.Abp.AspNetCore.VirtualFileSystem; + +public class NullWebContentFileProvider : IWebContentFileProvider +{ + public virtual IFileInfo GetFileInfo(string subpath) + { + return new NotFoundFileInfo(subpath); + } + + public virtual IDirectoryContents GetDirectoryContents(string subpath) + { + return new NotFoundDirectoryContents(); + } + + public virtual IChangeToken Watch(string filter) + { + return NullChangeToken.Singleton; + } +} diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/WebClientInfo/IWebClientInfoProvider.cs b/framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/WebClientInfo/IWebClientInfoProvider.cs similarity index 83% rename from framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/WebClientInfo/IWebClientInfoProvider.cs rename to framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/WebClientInfo/IWebClientInfoProvider.cs index abd92597d3..7cbb4ecae8 100644 --- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/WebClientInfo/IWebClientInfoProvider.cs +++ b/framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/WebClientInfo/IWebClientInfoProvider.cs @@ -5,4 +5,6 @@ public interface IWebClientInfoProvider string? BrowserInfo { get; } string? ClientIpAddress { get; } + + string? DeviceInfo { get; } } diff --git a/framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/WebClientInfo/NullWebClientInfoProvider.cs b/framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/WebClientInfo/NullWebClientInfoProvider.cs new file mode 100644 index 0000000000..9b83ffa4f3 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Abstractions/Volo/Abp/AspNetCore/WebClientInfo/NullWebClientInfoProvider.cs @@ -0,0 +1,10 @@ +namespace Volo.Abp.AspNetCore.WebClientInfo; + +public class NullWebClientInfoProvider : IWebClientInfoProvider +{ + public virtual string? BrowserInfo { get; } + + public virtual string? ClientIpAddress { get; } + + public virtual string? DeviceInfo { get; } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Bundling/AbpScripts.razor b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Bundling/AbpScripts.razor index 435e318afa..6735d54d14 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Bundling/AbpScripts.razor +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Bundling/AbpScripts.razor @@ -1,5 +1,7 @@ @using Volo.Abp +@implements IDisposable @inject IComponentBundleManager BundleManager +@inject PersistentComponentState PersistentComponentState @if (ScriptFiles != null) { @@ -18,16 +20,37 @@ private List? ScriptFiles { get; set; } + private PersistingComponentStateSubscription persistingSubscription; + protected override async Task OnInitializedAsync() { if (BundleName == null) { throw new AbpException("The BundleName parameter of the AbpScripts component can not be null!"); } - ScriptFiles = (await BundleManager.GetScriptBundleFilesAsync(BundleName!)).ToList(); + + persistingSubscription = PersistentComponentState.RegisterOnPersisting(PersistScriptFiles); + + if (PersistentComponentState.TryTakeFromJson>(nameof(ScriptFiles), out var restoredStyleFiles)) + { + ScriptFiles = restoredStyleFiles; + } + else + { + ScriptFiles = (await BundleManager.GetScriptBundleFilesAsync(BundleName!)).ToList(); + } + if (OperatingSystem.IsBrowser() && WebAssemblyScriptFiles != null) { - ScriptFiles.AddRange(WebAssemblyScriptFiles); + ScriptFiles?.AddRange(WebAssemblyScriptFiles); } } + + private Task PersistScriptFiles() + { + PersistentComponentState.PersistAsJson(nameof(ScriptFiles), ScriptFiles); + return Task.CompletedTask; + } + + public void Dispose() => persistingSubscription.Dispose(); } diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Bundling/AbpStyles.razor b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Bundling/AbpStyles.razor index 488caba797..bae9b382f3 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Bundling/AbpStyles.razor +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Bundling/AbpStyles.razor @@ -1,11 +1,13 @@ @using Volo.Abp +@implements IDisposable @inject IComponentBundleManager BundleManager +@inject PersistentComponentState PersistentComponentState @if (StyleFiles != null) { foreach (var file in StyleFiles) { - + } } @@ -18,16 +20,37 @@ private List? StyleFiles { get; set; } + private PersistingComponentStateSubscription persistingSubscription; + protected override async Task OnInitializedAsync() { if (BundleName == null) { throw new AbpException("The BundleName parameter of the AbpStyles component can not be null!"); } - StyleFiles = (await BundleManager.GetStyleBundleFilesAsync(BundleName!)).ToList(); + + persistingSubscription = PersistentComponentState.RegisterOnPersisting(PersistStyleFiles); + + if (PersistentComponentState.TryTakeFromJson>(nameof(StyleFiles), out var restoredStyleFiles)) + { + StyleFiles = restoredStyleFiles; + } + else + { + StyleFiles = (await BundleManager.GetStyleBundleFilesAsync(BundleName!)).ToList(); + } + if (OperatingSystem.IsBrowser() && WebAssemblyStyleFiles != null) { - StyleFiles.AddRange(WebAssemblyStyleFiles); + StyleFiles?.AddRange(WebAssemblyStyleFiles); } } + + private Task PersistStyleFiles() + { + PersistentComponentState.PersistAsJson(nameof(StyleFiles), StyleFiles); + return Task.CompletedTask; + } + + public void Dispose() => persistingSubscription.Dispose(); } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClientHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClientHelper.cs similarity index 83% rename from framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClientHelper.cs rename to framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClientHelper.cs index 740a79c884..cc1180fd20 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClientHelper.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/MvcCachedApplicationConfigurationClientHelper.cs @@ -3,7 +3,7 @@ using Volo.Abp.Users; namespace Volo.Abp.AspNetCore.Mvc.Client; -internal static class MvcCachedApplicationConfigurationClientHelper +public static class MvcCachedApplicationConfigurationClientHelper { public static string CreateCacheKey(ICurrentUser currentUser) { diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemoteDynamicClaimsPrincipalContributorCache.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemoteDynamicClaimsPrincipalContributorCache.cs index 738884fe06..f63c04e49c 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemoteDynamicClaimsPrincipalContributorCache.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client.Common/Volo/Abp/AspNetCore/Mvc/Client/RemoteDynamicClaimsPrincipalContributorCache.cs @@ -4,10 +4,12 @@ using System.Net.Http; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; +using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; using Volo.Abp.Caching; using Volo.Abp.Http.Client; using Volo.Abp.Http.Client.Authentication; using Volo.Abp.Security.Claims; +using Volo.Abp.Users; namespace Volo.Abp.AspNetCore.Mvc.Client; @@ -18,17 +20,23 @@ public class RemoteDynamicClaimsPrincipalContributorCache : RemoteDynamicClaimsP protected IDistributedCache Cache { get; } protected IHttpClientFactory HttpClientFactory { get; } protected IRemoteServiceHttpClientAuthenticator HttpClientAuthenticator { get; } + protected IDistributedCache ApplicationConfigurationDtoCache { get; } + protected ICurrentUser CurrentUser { get; } public RemoteDynamicClaimsPrincipalContributorCache( IDistributedCache cache, IHttpClientFactory httpClientFactory, IOptions abpClaimsPrincipalFactoryOptions, - IRemoteServiceHttpClientAuthenticator httpClientAuthenticator) + IRemoteServiceHttpClientAuthenticator httpClientAuthenticator, + IDistributedCache applicationConfigurationDtoCache, + ICurrentUser currentUser) : base(abpClaimsPrincipalFactoryOptions) { Cache = cache; HttpClientFactory = httpClientFactory; HttpClientAuthenticator = httpClientAuthenticator; + ApplicationConfigurationDtoCache = applicationConfigurationDtoCache; + CurrentUser = currentUser; } protected async override Task GetCacheAsync(Guid userId, Guid? tenantId = null) @@ -49,6 +57,7 @@ public class RemoteDynamicClaimsPrincipalContributorCache : RemoteDynamicClaimsP catch (Exception e) { Logger.LogWarning(e, $"Failed to refresh remote claims for user: {userId}"); + await ApplicationConfigurationDtoCache.RemoveAsync(MvcCachedApplicationConfigurationClientHelper.CreateCacheKey(CurrentUser)); throw; } } diff --git a/framework/src/Volo.Abp.AspNetCore/Volo.Abp.AspNetCore.csproj b/framework/src/Volo.Abp.AspNetCore/Volo.Abp.AspNetCore.csproj index 88b4506dc5..c6326e3e95 100644 --- a/framework/src/Volo.Abp.AspNetCore/Volo.Abp.AspNetCore.csproj +++ b/framework/src/Volo.Abp.AspNetCore/Volo.Abp.AspNetCore.csproj @@ -20,6 +20,7 @@ + @@ -30,6 +31,7 @@ + diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreModule.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreModule.cs index bad4b7c491..cda6aea27f 100644 --- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreModule.cs +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/AbpAspNetCoreModule.cs @@ -25,7 +25,8 @@ namespace Volo.Abp.AspNetCore; typeof(AbpHttpModule), typeof(AbpAuthorizationModule), typeof(AbpValidationModule), - typeof(AbpExceptionHandlingModule) + typeof(AbpExceptionHandlingModule), + typeof(AbpAspNetCoreAbstractionsModule) )] public class AbpAspNetCoreModule : AbpModule { diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpDynamicClaimsMiddleware.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpDynamicClaimsMiddleware.cs index 9c62fa8b25..181aaf3ec8 100644 --- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpDynamicClaimsMiddleware.cs +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Security/Claims/AbpDynamicClaimsMiddleware.cs @@ -1,4 +1,6 @@ +using System; using System.Threading.Tasks; +using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; @@ -16,8 +18,26 @@ public class AbpDynamicClaimsMiddleware : AbpMiddlewareBase, ITransientDependenc { if (context.RequestServices.GetRequiredService>().Value.IsDynamicClaimsEnabled) { + var authenticationType = context.User.Identity.AuthenticationType; var abpClaimsPrincipalFactory = context.RequestServices.GetRequiredService(); context.User = await abpClaimsPrincipalFactory.CreateDynamicAsync(context.User); + + if (context.User.Identity?.IsAuthenticated == false) + { + if (!authenticationType.IsNullOrWhiteSpace()) + { + var authenticationSchemeProvider = context.RequestServices.GetRequiredService(); + var scheme = await authenticationSchemeProvider.GetSchemeAsync(authenticationType); + if (scheme != null) + { + await context.SignOutAsync(scheme.Name); + } + } + else + { + await context.SignOutAsync(); + } + } } } diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/VirtualFileSystem/WebContentFileProvider.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/VirtualFileSystem/WebContentFileProvider.cs index fffc35792a..9814dd8c97 100644 --- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/VirtualFileSystem/WebContentFileProvider.cs +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/VirtualFileSystem/WebContentFileProvider.cs @@ -10,6 +10,7 @@ using Volo.Abp.VirtualFileSystem; namespace Volo.Abp.AspNetCore.VirtualFileSystem; +[Dependency(ReplaceServices = true)] public class WebContentFileProvider : IWebContentFileProvider, ISingletonDependency { private readonly IVirtualFileProvider _virtualFileProvider; diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/WebClientInfo/HttpContextWebClientInfoProvider.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/WebClientInfo/HttpContextWebClientInfoProvider.cs index 3c44cda4e3..6e450efbcd 100644 --- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/WebClientInfo/HttpContextWebClientInfoProvider.cs +++ b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/WebClientInfo/HttpContextWebClientInfoProvider.cs @@ -1,10 +1,12 @@ using System; +using DeviceDetectorNET; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using Volo.Abp.DependencyInjection; namespace Volo.Abp.AspNetCore.WebClientInfo; +[Dependency(ReplaceServices = true)] public class HttpContextWebClientInfoProvider : IWebClientInfoProvider, ITransientDependency { protected ILogger Logger { get; } @@ -22,6 +24,8 @@ public class HttpContextWebClientInfoProvider : IWebClientInfoProvider, ITransie public string? ClientIpAddress => GetClientIpAddress(); + public string? DeviceInfo => GetDeviceInfo(); + protected virtual string? GetBrowserInfo() { return HttpContextAccessor.HttpContext?.Request?.Headers?["User-Agent"]; @@ -39,4 +43,30 @@ public class HttpContextWebClientInfoProvider : IWebClientInfoProvider, ITransie return null; } } + + protected virtual string? GetDeviceInfo() + { + string? deviceInfo = null; + var deviceDetector = new DeviceDetector(GetBrowserInfo()); + deviceDetector.Parse(); + if (!deviceDetector.IsParsed()) + { + return deviceInfo; + } + + var osInfo = deviceDetector.GetOs(); + if (osInfo.Success) + { + deviceInfo = osInfo.Match.Name; + } + + var clientInfo = deviceDetector.GetClient(); + if (clientInfo.Success) + { + deviceInfo = deviceInfo.IsNullOrWhiteSpace() ? clientInfo.Match.Name : deviceInfo + " " + clientInfo.Match.Name; + } + + return deviceInfo; + } + } diff --git a/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ApplicationApiDescriptionModel.cs b/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ApplicationApiDescriptionModel.cs index 399b7caa10..f0cf747ac1 100644 --- a/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ApplicationApiDescriptionModel.cs +++ b/framework/src/Volo.Abp.Http/Volo/Abp/Http/Modeling/ApplicationApiDescriptionModel.cs @@ -21,7 +21,7 @@ public class ApplicationApiDescriptionModel { return new ApplicationApiDescriptionModel { - Modules = new ConcurrentDictionary(), //TODO: Why ConcurrentDictionary? + Modules = new Dictionary(), Types = new SortedDictionary() }; } diff --git a/framework/src/Volo.Abp.Security/System/Security/Principal/AbpClaimsIdentityExtensions.cs b/framework/src/Volo.Abp.Security/System/Security/Principal/AbpClaimsIdentityExtensions.cs index 2661298405..0a89ba7a3f 100644 --- a/framework/src/Volo.Abp.Security/System/Security/Principal/AbpClaimsIdentityExtensions.cs +++ b/framework/src/Volo.Abp.Security/System/Security/Principal/AbpClaimsIdentityExtensions.cs @@ -276,4 +276,32 @@ public static class AbpClaimsIdentityExtensions return principal; } + + public static string? FindSessionId([NotNull] this IIdentity identity) + { + Check.NotNull(identity, nameof(identity)); + + var claimsIdentity = identity as ClaimsIdentity; + + var sessionIdOrNull = claimsIdentity?.Claims?.FirstOrDefault(c => c.Type == AbpClaimTypes.SessionId); + if (sessionIdOrNull == null || sessionIdOrNull.Value.IsNullOrWhiteSpace()) + { + return null; + } + + return sessionIdOrNull.Value; + } + + public static string? FindSessionId([NotNull] this ClaimsPrincipal principal) + { + Check.NotNull(principal, nameof(principal)); + + var sessionIdOrNull = principal.Claims?.FirstOrDefault(c => c.Type == AbpClaimTypes.SessionId); + if (sessionIdOrNull == null || sessionIdOrNull.Value.IsNullOrWhiteSpace()) + { + return null; + } + + return sessionIdOrNull.Value; + } } diff --git a/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/AbpClaimTypes.cs b/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/AbpClaimTypes.cs index 3ce75e36d8..0e7f098174 100644 --- a/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/AbpClaimTypes.cs +++ b/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/AbpClaimTypes.cs @@ -97,4 +97,9 @@ public static class AbpClaimTypes /// Default: "remember_me". /// public static string RememberMe { get; set; } = "remember_me"; + + /// + /// Default: "session_id". + /// + public static string SessionId { get; set; } = "session_id"; } diff --git a/framework/src/Volo.Abp.Security/Volo/Abp/Users/CurrentUserExtensions.cs b/framework/src/Volo.Abp.Security/Volo/Abp/Users/CurrentUserExtensions.cs index b702bcffde..e40c9a9fd7 100644 --- a/framework/src/Volo.Abp.Security/Volo/Abp/Users/CurrentUserExtensions.cs +++ b/framework/src/Volo.Abp.Security/Volo/Abp/Users/CurrentUserExtensions.cs @@ -70,4 +70,16 @@ public static class CurrentUserExtensions { return currentUser.FindClaimValue(AbpClaimTypes.ImpersonatorUserName); } + + public static string GetSessionId([NotNull] this ICurrentUser currentUser) + { + var sessionId = currentUser.FindSessionId(); + Debug.Assert(sessionId != null, "sessionId != null"); + return sessionId!; + } + + public static string? FindSessionId([NotNull] this ICurrentUser currentUser) + { + return currentUser.FindClaimValue(AbpClaimTypes.SessionId); + } } diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ar.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ar.json index a812779c0c..c5a82323a7 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ar.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ar.json @@ -13,7 +13,8 @@ "SavingWithThreeDot": "حفظ...", "Actions": "الإجراءات", "Delete": "حذف", - "SuccessfullyDeleted": "تم الحذف بنجاح", + "SavedSuccessfully": "تم الحفظ بنجاح", + "DeletedSuccessfully": "تم الحذف بنجاح", "Edit": "تعديل", "Refresh": "تحديث", "Language": "لغة", @@ -59,4 +60,4 @@ "Theme": "سمة", "NotAssigned": "غيرمعتمد" } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/cs.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/cs.json index 3051f02eb5..0ad24147ad 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/cs.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/cs.json @@ -13,7 +13,8 @@ "SavingWithThreeDot": "Ukládám...", "Actions": "Akce", "Delete": "Smazat", - "SuccessfullyDeleted": "Úspěšně smazáno", + "SavedSuccessfully": "Úspěšně uloženo", + "DeletedSuccessfully": "Úspěšně smazáno", "Edit": "Upravit", "Refresh": "Obnovit", "Language": "Jazyk", @@ -59,4 +60,4 @@ "Theme": "Téma", "NotAssigned": "Nepřiřazena" } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/de.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/de.json index e7f64a85de..4ccf318098 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/de.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/de.json @@ -13,7 +13,8 @@ "SavingWithThreeDot": "Speichern...", "Actions": "Aktionen", "Delete": "Löschen", - "SuccessfullyDeleted": "Erfolgreich gelöscht", + "SavedSuccessfully": "Erfolgreich gespeichert", + "DeletedSuccessfully": "Erfolgreich gelöscht", "Edit": "Bearbeiten", "Refresh": "Aktualisieren", "Language": "Sprache", @@ -59,4 +60,4 @@ "Theme": "Thema", "NotAssigned": "Nicht zugeordnet" } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/el.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/el.json index 8cb7b4c0dc..41516ba8ea 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/el.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/el.json @@ -13,7 +13,8 @@ "SavingWithThreeDot": "Αποθηκεύεται...", "Actions": "Ενέργειες", "Delete": "Διαγραφή", - "SuccessfullyDeleted": "Διαγράφηκε με επιτυχία", + "SavedSuccessfully": "Αποθηκεύτηκε με επιτυχία", + "DeletedSuccessfully": "Διαγράφηκε με επιτυχία", "Edit": "Επεξεργασία", "Refresh": "Ανανέωση", "Language": "Γλώσσα", @@ -49,8 +50,8 @@ "ItemWillBeDeletedMessageWithFormat": "Το {0} θα διαγραφεί", "ItemWillBeDeletedMessage": "Αυτό το στοιχείο θα διαγραφεί!", "ManageYourAccount": "Διαχείριση Λογαριασμού", - "OthersGroup":"άλλος", + "OthersGroup": "άλλος", "Today": "Σήμερα", "Apply": "Ισχύουν" } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en-GB.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en-GB.json index 68ad3dda07..9376548bf2 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en-GB.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en-GB.json @@ -13,7 +13,8 @@ "SavingWithThreeDot": "Saving", "Actions": "Actions", "Delete": "Delete", - "SuccessfullyDeleted": "Successfully deleted", + "SavedSuccessfully": "Saved successfully", + "DeletedSuccessfully": "Deleted successfully", "Edit": "Edit", "Refresh": "Refresh", "Language": "Language", @@ -54,4 +55,4 @@ "Today": "Today", "Apply": "Apply" } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en.json index 5a9ee621a0..5bac61fe4d 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en.json @@ -13,7 +13,8 @@ "SavingWithThreeDot": "Saving...", "Actions": "Actions", "Delete": "Delete", - "SuccessfullyDeleted": "Successfully deleted", + "SavedSuccessfully": "Saved successfully", + "DeletedSuccessfully": "Deleted successfully", "Edit": "Edit", "Refresh": "Refresh", "Language": "Language", diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/es.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/es.json index b5efa33449..3b1cf8620f 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/es.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/es.json @@ -13,7 +13,8 @@ "SavingWithThreeDot": "Guardando...", "Actions": "Opciones", "Delete": "Borrar", - "SuccessfullyDeleted": "Eliminado con éxito", + "SavedSuccessfully": "Guardado con éxito", + "DeletedSuccessfully": "Eliminado con éxito", "Edit": "Editar", "Refresh": "Actualizar", "Language": "Idioma", @@ -59,4 +60,4 @@ "Theme": "Tema", "NotAssigned": "No asignado" } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/fa.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/fa.json index bcc6250656..102e497c2a 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/fa.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/fa.json @@ -13,7 +13,8 @@ "SavingWithThreeDot": "ذخیره...", "Actions": "عملیات", "Delete": "حذف", - "SuccessfullyDeleted": "با موفقیت حذف شد", + "SavedSuccessfully": "با موفقیت ذخیره شد", + "DeletedSuccessfully": "با موفقیت حذف شد", "Edit": "ویرایش", "Refresh": "رفرش", "Language": "زبان", diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/fi.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/fi.json index 13f1855235..73a29e3e95 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/fi.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/fi.json @@ -13,7 +13,8 @@ "SavingWithThreeDot": "Tallennetaan...", "Actions": "Toiminnot", "Delete": "Poista", - "SuccessfullyDeleted": "Poistettu onnistuneesti", + "SavedSuccessfully": "Tallennettu onnistuneesti", + "DeletedSuccessfully": "Poistettu onnistuneesti", "Edit": "Muokkaa", "Refresh": "Virkistä", "Language": "Kieli", @@ -59,4 +60,4 @@ "Theme": "Teema", "NotAssigned": "Ei määritetty" } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/fr.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/fr.json index b574c4e179..734056ac05 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/fr.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/fr.json @@ -13,7 +13,8 @@ "SavingWithThreeDot": "Enregistrement...", "Actions": "Actions", "Delete": "Supprimer", - "SuccessfullyDeleted": "Supprimé avec succès", + "SavedSuccessfully": "Enregistré avec succès", + "DeletedSuccessfully": "Supprimé avec succès", "Edit": "Modifier", "Refresh": "Actualiser", "Language": "Langue", @@ -59,4 +60,4 @@ "Theme": "Thème", "NotAssigned": "Non attribué" } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/hi.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/hi.json index a216d8bf0d..d5305a50ac 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/hi.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/hi.json @@ -13,7 +13,8 @@ "SavingWithThreeDot": "सहेजा जा रहा है...", "Actions": "कार्रवाई", "Delete": "हटाएं", - "SuccessfullyDeleted": "सफलतापूर्वक हटा दिया गया", + "SavedSuccessfully": "सफलतापूर्वक सहेजा गया", + "DeletedSuccessfully": "सफलतापूर्वक हटा दिया गया", "Edit": "संपादित करें", "Refresh": "ताज़ा करना", "Language": "भाषा: हिन्दी", @@ -59,4 +60,4 @@ "Theme": "विषय", "NotAssigned": "सौंपा नहीं गया है" } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/hr.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/hr.json index 7a5af21a9a..fab7011098 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/hr.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/hr.json @@ -13,7 +13,8 @@ "SavingWithThreeDot": "Spremanje...", "Actions": "Akcije", "Delete": "Izbrisati", - "SuccessfullyDeleted": "Uspješno izbrisano", + "SavedSuccessfully": "Uspešno zabeleženo", + "DeletedSuccessfully": "Uspješno izbrisano", "Edit": "Uredi", "Refresh": "Osvježi", "Language": "Jezik", @@ -59,4 +60,4 @@ "Theme": "Tema", "NotAssigned": "Nije dodijeljeno" } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/hu.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/hu.json index 7b69f58cb2..be6b1a94a2 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/hu.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/hu.json @@ -13,7 +13,8 @@ "SavingWithThreeDot": "Mentés...", "Actions": "Műveletek", "Delete": "Törlés", - "SuccessfullyDeleted": "Sikeresen törölve", + "SavedSuccessfully": "Sikeresen mentve", + "DeletedSuccessfully": "Sikeresen törölve", "Edit": "Szerkesztés", "Refresh": "Frissítés", "Language": "Nyelv", @@ -59,4 +60,4 @@ "Theme": "Téma", "NotAssigned": "Nem kijelölt" } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/is.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/is.json index 6115bc6866..635fc4d6d1 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/is.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/is.json @@ -13,7 +13,8 @@ "SavingWithThreeDot": "Er að vista...", "Actions": "Aðgerðir", "Delete": "Eyða", - "SuccessfullyDeleted": "Tókst að eyða", + "SavedSuccessfully": "Tókst að vista", + "DeletedSuccessfully": "Tókst að eyða", "Edit": "Breyta", "Refresh": "Endurhlaða", "Language": "Tungumál", @@ -59,4 +60,4 @@ "Theme": "Þema", "NotAssigned": "Ekki skráður" } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/it.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/it.json index dfeff1d476..bb8bb2ee31 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/it.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/it.json @@ -13,7 +13,8 @@ "SavingWithThreeDot": "Salvataggio...", "Actions": "Azioni", "Delete": "Elimina", - "SuccessfullyDeleted": "Eliminato con successo", + "SavedSuccessfully": "Salvato con successo", + "DeletedSuccessfully": "Eliminato con successo", "Edit": "Modifica", "Refresh": "Ricarica", "Language": "Lingua", @@ -59,4 +60,4 @@ "Theme": "Tema", "NotAssigned": "Non assegnato" } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/nl.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/nl.json index 98c7f0980d..b074253db8 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/nl.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/nl.json @@ -13,7 +13,8 @@ "SavingWithThreeDot": "Opslaan...", "Actions": "Acties", "Delete": "Verwijder", - "SuccessfullyDeleted": "Succesvol verwijderd", + "SavedSuccessfully": "Succesvol opgeslagen", + "DeletedSuccessfully": "Succesvol verwijderd", "Edit": "Bewerk", "Refresh": "Ververs", "Language": "Taal", @@ -59,4 +60,4 @@ "Theme": "Thema", "NotAssigned": "Niet toegekend" } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/pl-PL.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/pl-PL.json index 027957fec2..1f5135b80a 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/pl-PL.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/pl-PL.json @@ -13,7 +13,8 @@ "SavingWithThreeDot": "Zapisywanie...", "Actions": "Akcje", "Delete": "Usuń", - "SuccessfullyDeleted": "Pomyślnie usunięto", + "SavedSuccessfully": "Pomyślnie zapisano", + "DeletedSuccessfully": "Pomyślnie usunięto", "Edit": "Edytuj", "Refresh": "Odśwież", "Language": "Język", @@ -59,4 +60,4 @@ "Theme": "Temat", "NotAssigned": "Nie przypisano" } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/pt-BR.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/pt-BR.json index d43cd75d94..51a1ce8ba0 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/pt-BR.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/pt-BR.json @@ -13,7 +13,8 @@ "SavingWithThreeDot": "Salvando...", "Actions": "Ações", "Delete": "Excluir", - "SuccessfullyDeleted": "Excluído com sucesso", + "SavedSuccessfully": "Salvo com sucesso", + "DeletedSuccessfully": "Excluído com sucesso", "Edit": "Editar", "Refresh": "Atualizar", "Language": "Idioma", @@ -59,4 +60,4 @@ "Theme": "Tema", "NotAssigned": "Não atribuído" } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ro-RO.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ro-RO.json index 53140c9f8e..2a2151b081 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ro-RO.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ro-RO.json @@ -13,7 +13,8 @@ "SavingWithThreeDot": "Se salvează...", "Actions": "Acţiuni", "Delete": "Şterge", - "SuccessfullyDeleted": "Șters cu succes", + "SavedSuccessfully": "Salvat cu succes", + "DeletedSuccessfully": "Șters cu succes", "Edit": "Editează", "Refresh": "Reîncarcă", "Language": "Limba", @@ -59,4 +60,4 @@ "Theme": "Temă", "NotAssigned": "Nealocat" } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ru.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ru.json index 19c7f6e80c..f78af7c6a7 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ru.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/ru.json @@ -13,7 +13,8 @@ "SavingWithThreeDot": "Сохранение...", "Actions": "Действия", "Delete": "Удалить", - "SuccessfullyDeleted": "Успешно удалено", + "SavedSuccessfully": "Успешно сохранено", + "DeletedSuccessfully": "Успешно удалено", "Edit": "Редактировать", "Refresh": "Обновить", "Language": "Язык", @@ -59,4 +60,4 @@ "Theme": "Тема", "NotAssigned": "Не назначен" } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/sk.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/sk.json index ef823bfcd9..c0e3c9f3bd 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/sk.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/sk.json @@ -13,7 +13,8 @@ "SavingWithThreeDot": "Úkladanie...", "Actions": "Akcie", "Delete": "Odstrániť", - "SuccessfullyDeleted": "Úspešne odstránené", + "SavedSuccessfully": "Úspešne uložené", + "DeletedSuccessfully": "Úspešne odstránené", "Edit": "Upraviť", "Refresh": "Obnoviť", "Language": "Jazyk", @@ -59,4 +60,4 @@ "Theme": "Téma", "NotAssigned": "Nepridelené" } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/sl.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/sl.json index a9cb2aadd1..d417af7cf7 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/sl.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/sl.json @@ -13,7 +13,8 @@ "SavingWithThreeDot": "Shranjujem...", "Actions": "Dejanja", "Delete": "Izbriši", - "SuccessfullyDeleted": "Uspešno izbrisano", + "SavedSuccessfully": "Uspešno shranjeno", + "DeletedSuccessfully": "Uspešno izbrisano", "Edit": "Uredi", "Refresh": "Osveži", "Language": "Jezik", @@ -59,4 +60,4 @@ "Theme": "Tema", "NotAssigned": "Ni dodeljena" } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/tr.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/tr.json index dda41fd75e..ae54b8d15e 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/tr.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/tr.json @@ -13,7 +13,8 @@ "SavingWithThreeDot": "Kaydediliyor...", "Actions": "İşlemler", "Delete": "Sil", - "SuccessfullyDeleted": "Başarıyla silindi", + "SavedSuccessfully": "Başarıyla kaydedildi", + "DeletedSuccessfully": "Başarıyla silindi", "Edit": "Düzenle", "Refresh": "Yenile", "Language": "Dil", diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/vi.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/vi.json index d352b69ca2..1204aa588b 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/vi.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/vi.json @@ -13,7 +13,8 @@ "SavingWithThreeDot": "Đang lưu...", "Actions": "Hành động", "Delete": "Xóa", - "SuccessfullyDeleted": "Đã xóa thành công", + "SavedSuccessfully": "Đã lưu thành công", + "DeletedSuccessfully": "Đã xóa thành công", "Edit": "Sửa", "Refresh": "Làm mới", "Language": "Ngôn ngữ", @@ -59,4 +60,4 @@ "Theme": "chủ đề", "NotAssigned": "Không được chỉ định" } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/zh-Hans.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/zh-Hans.json index cbc45a5a08..6d55191b06 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/zh-Hans.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/zh-Hans.json @@ -13,7 +13,8 @@ "SavingWithThreeDot": "保存中...", "Actions": "操作", "Delete": "删除", - "SuccessfullyDeleted": "删除成功", + "SavedSuccessfully": "保存成功", + "DeletedSuccessfully": "删除成功", "Edit": "编辑", "Refresh": "刷新", "Language": "语言", @@ -59,4 +60,4 @@ "Theme": "主题", "NotAssigned": "未分配" } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/zh-Hant.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/zh-Hant.json index 8223d79a43..51bdc6de5f 100644 --- a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/zh-Hant.json +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/zh-Hant.json @@ -13,7 +13,8 @@ "SavingWithThreeDot": "保存中...", "Actions": "操作", "Delete": "刪除", - "SuccessfullyDeleted": "刪除成功", + "SavedSuccessfully": "保存成功", + "DeletedSuccessfully": "刪除成功", "Edit": "修改", "Refresh": "更新", "Language": "語言", @@ -59,4 +60,4 @@ "Theme": "主題", "NotAssigned": "未分配" } -} \ No newline at end of file +} diff --git a/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Documents/DocumentAdminAppService.cs b/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Documents/DocumentAdminAppService.cs index 9356ba9c38..8e70be19e4 100644 --- a/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Documents/DocumentAdminAppService.cs +++ b/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Documents/DocumentAdminAppService.cs @@ -57,7 +57,7 @@ namespace Volo.Docs.Admin.Documents var versionCacheKey = CacheKeyGenerator.GenerateProjectVersionsCacheKey(project); await _versionCache.RemoveAsync(versionCacheKey, true); - var documents = await _documentRepository.GetListByProjectId(project.Id); + var documents = await _documentRepository.GetListWithoutDetailsByProjectId(project.Id); var documentUpdateInfoCacheKeys = documents.Select(document => CacheKeyGenerator.GenerateDocumentUpdateInfoCacheKey( @@ -69,10 +69,8 @@ namespace Volo.Docs.Admin.Documents ); await _documentUpdateCache.RemoveManyAsync(documentUpdateInfoCacheKeys); - - documents.ForEach(document => document.LastCachedTime = DateTime.MinValue); - await _documentRepository.UpdateManyAsync(documents); + await _documentRepository.UpdateProjectLastCachedTimeAsync(project.Id, DateTime.MinValue); } public virtual async Task PullAllAsync(PullAllDocumentInput input) diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/DocumentWithoutDetails.cs b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/DocumentWithoutDetails.cs index 8adade5be2..2aaf54aee4 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/DocumentWithoutDetails.cs +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/DocumentWithoutDetails.cs @@ -5,6 +5,8 @@ namespace Volo.Docs.Documents public class DocumentWithoutDetails { public Guid Id { get; set; } + + public string Name { get; set; } public virtual string Version { get; set; } diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/IDocumentRepository.cs b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/IDocumentRepository.cs index b1580f379a..7dc8f13147 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/IDocumentRepository.cs +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/IDocumentRepository.cs @@ -12,6 +12,9 @@ namespace Volo.Docs.Documents Task> GetUniqueListDocumentInfoAsync(CancellationToken cancellationToken = default); Task> GetListByProjectId(Guid projectId, CancellationToken cancellationToken = default); + + Task UpdateProjectLastCachedTimeAsync(Guid projectId, DateTime cachedTime, + CancellationToken cancellationToken = default); Task FindAsync(Guid projectId, string name, diff --git a/modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/Documents/EFCoreDocumentRepository.cs b/modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/Documents/EFCoreDocumentRepository.cs index 700203e7dd..1120e36d01 100644 --- a/modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/Documents/EFCoreDocumentRepository.cs +++ b/modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/Documents/EFCoreDocumentRepository.cs @@ -28,6 +28,7 @@ namespace Volo.Docs.Documents Version = x.Version, LanguageCode = x.LanguageCode, Format = x.Format, + Name = x.Name }) .ToListAsync(GetCancellationToken(cancellationToken)); } @@ -55,6 +56,12 @@ namespace Volo.Docs.Documents return await (await GetDbSetAsync()).Where(d => d.ProjectId == projectId).ToListAsync(GetCancellationToken(cancellationToken)); } + public async Task UpdateProjectLastCachedTimeAsync(Guid projectId, DateTime cachedTime, + CancellationToken cancellationToken = default) + { + await (await GetDbSetAsync()).Where(d => d.ProjectId == projectId).ExecuteUpdateAsync(x => x.SetProperty(d => d.LastCachedTime, cachedTime), GetCancellationToken(cancellationToken)); + } + public virtual async Task> GetListAsync(Guid? projectId, string version, string name, CancellationToken cancellationToken = default) { return await (await GetDbSetAsync()) diff --git a/modules/docs/src/Volo.Docs.MongoDB/Volo/Docs/Documents/MongoDocumentRepository.cs b/modules/docs/src/Volo.Docs.MongoDB/Volo/Docs/Documents/MongoDocumentRepository.cs index 1cd93545a5..9a3750deb0 100644 --- a/modules/docs/src/Volo.Docs.MongoDB/Volo/Docs/Documents/MongoDocumentRepository.cs +++ b/modules/docs/src/Volo.Docs.MongoDB/Volo/Docs/Documents/MongoDocumentRepository.cs @@ -29,7 +29,8 @@ namespace Volo.Docs.Documents Id = x.Id, Version = x.Version, LanguageCode = x.LanguageCode, - Format = x.Format + Format = x.Format, + Name = x.Name }) .ToListAsync(GetCancellationToken(cancellationToken)); } @@ -53,6 +54,17 @@ namespace Volo.Docs.Documents return await (await GetMongoQueryableAsync(cancellationToken)).Where(d => d.ProjectId == projectId).ToListAsync(GetCancellationToken(cancellationToken)); } + public async Task UpdateProjectLastCachedTimeAsync(Guid projectId, DateTime cachedTime, + CancellationToken cancellationToken = default) + { + var collection = await GetCollectionAsync(cancellationToken); + await collection.UpdateManyAsync( + Builders.Filter.Eq(x => x.ProjectId, projectId), + Builders.Update.Set(x => x.LastCachedTime, cachedTime), + cancellationToken: GetCancellationToken(cancellationToken) + ); + } + public virtual async Task FindAsync(Guid projectId, string name, string languageCode, string version, bool includeDetails = true, CancellationToken cancellationToken = default) diff --git a/modules/docs/test/Volo.Docs.TestBase/Volo/Docs/DocumentRepository_Tests.cs b/modules/docs/test/Volo.Docs.TestBase/Volo/Docs/DocumentRepository_Tests.cs index ed0769ccc1..742f80fe17 100644 --- a/modules/docs/test/Volo.Docs.TestBase/Volo/Docs/DocumentRepository_Tests.cs +++ b/modules/docs/test/Volo.Docs.TestBase/Volo/Docs/DocumentRepository_Tests.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System; +using System.Threading.Tasks; using Shouldly; using Volo.Abp.Modularity; using Volo.Docs.Documents; @@ -34,5 +35,13 @@ namespace Volo.Docs (await DocumentRepository.GetListAsync()).ShouldBeEmpty(); } + + [Fact] + public async Task UpdateProjectLastCachedTimeAsync() + { + await DocumentRepository.UpdateProjectLastCachedTimeAsync(DocsTestData.ProjectId, DateTime.MinValue); + var documentsAfterClear = await DocumentRepository.GetListByProjectId(DocsTestData.ProjectId); + documentsAfterClear.ForEach(d => d.LastCachedTime.ShouldBe(DateTime.MinValue)); + } } } diff --git a/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpIdentityAspNetCoreModule.cs b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpIdentityAspNetCoreModule.cs index 9b38e2e25a..d261068adb 100644 --- a/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpIdentityAspNetCoreModule.cs +++ b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpIdentityAspNetCoreModule.cs @@ -1,5 +1,7 @@ -using Microsoft.AspNetCore.Identity; +using System; +using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using Volo.Abp.Modularity; using static Volo.Abp.Identity.AspNetCore.AbpSecurityStampValidatorCallback; @@ -45,9 +47,11 @@ public class AbpIdentityAspNetCoreModule : AbpModule public override void PostConfigureServices(ServiceConfigurationContext context) { - Configure(options => - { - options.UpdatePrincipal(); - }); + context.Services.AddOptions() + .Configure((securityStampValidatorOptions, serviceProvider) => + { + var abpRefreshingPrincipalOptions = serviceProvider.GetRequiredService>().Value; + securityStampValidatorOptions.UpdatePrincipal(abpRefreshingPrincipalOptions); + }); } } diff --git a/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpRefreshingPrincipalOptions.cs b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpRefreshingPrincipalOptions.cs new file mode 100644 index 0000000000..55e9007d6c --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpRefreshingPrincipalOptions.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using Volo.Abp.Security.Claims; + +namespace Volo.Abp.Identity.AspNetCore; + +public class AbpRefreshingPrincipalOptions +{ + public List CurrentPrincipalKeepClaimTypes { get; set; } + + public AbpRefreshingPrincipalOptions() + { + CurrentPrincipalKeepClaimTypes = new List + { + AbpClaimTypes.SessionId + }; + } +} diff --git a/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSecurityStampValidatorCallback.cs b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSecurityStampValidatorCallback.cs index 63bed70dfd..7108d30a5b 100644 --- a/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSecurityStampValidatorCallback.cs +++ b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSecurityStampValidatorCallback.cs @@ -1,5 +1,7 @@ using System.Linq; +using System.Security.Principal; using System.Threading.Tasks; +using JetBrains.Annotations; using Microsoft.AspNetCore.Identity; namespace Volo.Abp.Identity.AspNetCore; @@ -17,8 +19,9 @@ public class AbpSecurityStampValidatorCallback /// This is needed to preserve claims such as idp, auth_time, amr. /// /// The context. + /// The AbpRefreshingPrincipalOptions. /// - public static Task UpdatePrincipal(SecurityStampRefreshingPrincipalContext context) + public static Task UpdatePrincipal(SecurityStampRefreshingPrincipalContext context, AbpRefreshingPrincipalOptions refreshingPrincipalOptions) { var newClaimTypes = context.NewPrincipal.Claims.Select(x => x.Type).ToArray(); var currentClaimsToKeep = context.CurrentPrincipal.Claims.Where(x => !newClaimTypes.Contains(x.Type)).ToArray(); @@ -26,6 +29,18 @@ public class AbpSecurityStampValidatorCallback var id = context.NewPrincipal.Identities.First(); id.AddClaims(currentClaimsToKeep); + if (refreshingPrincipalOptions.CurrentPrincipalKeepClaimTypes.Any()) + { + foreach (var claimType in refreshingPrincipalOptions.CurrentPrincipalKeepClaimTypes) + { + var sessionIdClaim = context.CurrentPrincipal.Claims.FirstOrDefault(x => x.Type == claimType); + if (sessionIdClaim != null) + { + id.AddOrReplace(sessionIdClaim); + } + } + } + return Task.CompletedTask; } } diff --git a/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/SecurityStampValidatorOptionsExtensions.cs b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/SecurityStampValidatorOptionsExtensions.cs index d1c51fbf41..009e170310 100644 --- a/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/SecurityStampValidatorOptionsExtensions.cs +++ b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/SecurityStampValidatorOptionsExtensions.cs @@ -5,12 +5,12 @@ namespace Volo.Abp.Identity.AspNetCore; public static class SecurityStampValidatorOptionsExtensions { - public static SecurityStampValidatorOptions UpdatePrincipal(this SecurityStampValidatorOptions options) + public static SecurityStampValidatorOptions UpdatePrincipal(this SecurityStampValidatorOptions options, AbpRefreshingPrincipalOptions abpRefreshingPrincipalOptions) { var previousOnRefreshingPrincipal = options.OnRefreshingPrincipal; options.OnRefreshingPrincipal = async context => { - await SecurityStampValidatorCallback.UpdatePrincipal(context); + await SecurityStampValidatorCallback.UpdatePrincipal(context, abpRefreshingPrincipalOptions); if(previousOnRefreshingPrincipal != null) { await previousOnRefreshingPrincipal.Invoke(context); diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentitySessionConsts.cs b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentitySessionConsts.cs new file mode 100644 index 0000000000..96cb8df5c9 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentitySessionConsts.cs @@ -0,0 +1,14 @@ +namespace Volo.Abp.Identity; + +public class IdentitySessionConsts +{ + public static int MaxSessionIdLength { get; set; } = 128; + + public static int MaxDeviceLength { get; set; } = 64; + + public static int MaxDeviceInfoLength { get; set; } = 64; + + public static int MaxClientIdLength { get; set; } = 64; + + public static int MaxIpAddressesLength { get; set; } = 256; +} diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentitySessionDevices.cs b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentitySessionDevices.cs new file mode 100644 index 0000000000..ff8e470bae --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentitySessionDevices.cs @@ -0,0 +1,10 @@ +namespace Volo.Abp.Identity; + +public static class IdentitySessionDevices +{ + public const string Web = "Web"; + + public const string OAuth = "OAuth"; + + public const string Mobile = "Mobile"; +} diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentitySecurityLogRepository.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentitySecurityLogRepository.cs index 2ceaa8ed4c..8a1e50795f 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentitySecurityLogRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentitySecurityLogRepository.cs @@ -10,7 +10,7 @@ public interface IIdentitySecurityLogRepository : IBasicRepository> GetListAsync( string sorting = null, - int maxResultCount = 50, + int maxResultCount = int.MaxValue, int skipCount = 0, DateTime? startTime = null, DateTime? endTime = null, diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentitySessionRepository.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentitySessionRepository.cs new file mode 100644 index 0000000000..d40fbbcc95 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentitySessionRepository.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.Domain.Repositories; + +namespace Volo.Abp.Identity; + +public interface IIdentitySessionRepository : IBasicRepository +{ + Task FindAsync(string sessionId, CancellationToken cancellationToken = default); + + Task GetAsync(string sessionId, CancellationToken cancellationToken = default); + + Task> GetListAsync( + string sorting = null, + int maxResultCount = int.MaxValue, + int skipCount = 0, + Guid? userId = null, + string device = null, + string clientId = null, + CancellationToken cancellationToken = default); + + Task GetCountAsync( + Guid? userId = null, + string device = null, + string clientId = null, + CancellationToken cancellationToken = default); + + Task DeleteAllAsync(Guid userId, Guid? exceptSessionId = null, CancellationToken cancellationToken = default); + + Task DeleteAllAsync(Guid userId, string device, Guid? exceptSessionId = null, CancellationToken cancellationToken = default); + + Task DeleteAllAsync(TimeSpan inactiveTimeSpan, CancellationToken cancellationToken = default); +} diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentitySession.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentitySession.cs new file mode 100644 index 0000000000..c25a6b2e82 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentitySession.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; +using Volo.Abp.Domain.Entities; +using Volo.Abp.MultiTenancy; + +namespace Volo.Abp.Identity; + +public class IdentitySession : BasicAggregateRoot, IMultiTenant +{ + public virtual string SessionId { get; protected set; } + + /// + /// Web, Mobile ... + /// + public virtual string Device { get; protected set; } + + public virtual string DeviceInfo { get; protected set; } + + public virtual Guid? TenantId { get; protected set; } + + public virtual Guid UserId { get; protected set; } + + public virtual string ClientId { get; set; } + + public virtual string IpAddresses { get; protected set; } + + public virtual DateTime SignedIn { get; protected set; } + + public virtual DateTime? LastAccessed { get; protected set; } + + protected IdentitySession() + { + + } + + public IdentitySession( + Guid id, + string sessionId, + string device, + string deviceInfo, + Guid userId, + Guid? tenantId, + string clientId, + string ipAddresses, + DateTime signedIn, + DateTime? lastAccessed = null) + { + Id = id; + SessionId = sessionId; + Device = device; + DeviceInfo = deviceInfo; + UserId = userId; + TenantId = tenantId; + ClientId = clientId; + IpAddresses = ipAddresses; + SignedIn = signedIn; + LastAccessed = lastAccessed; + } + + public void SetSignedInTime(DateTime signedIn) + { + SignedIn = signedIn; + } + + public void UpdateLastAccessedTime(DateTime? lastAccessed) + { + LastAccessed = lastAccessed; + } + + public void SetIpAddresses(IEnumerable ipAddresses) + { + IpAddresses = JoinAsString(ipAddresses); + } + + public IEnumerable GetIpAddresses() + { + return GetArrayFromString(IpAddresses); + } + + private static string JoinAsString(IEnumerable list) + { + var serialized = string.Join(",", list); + return serialized.IsNullOrWhiteSpace() ? null : serialized; + } + + private string[] GetArrayFromString(string str) + { + return str?.Split(",", StringSplitOptions.RemoveEmptyEntries) ?? Array.Empty(); + } +} diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/AbpIdentityEntityFrameworkCoreModule.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/AbpIdentityEntityFrameworkCoreModule.cs index a58a73a996..c9dcc70e68 100644 --- a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/AbpIdentityEntityFrameworkCoreModule.cs +++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/AbpIdentityEntityFrameworkCoreModule.cs @@ -17,9 +17,10 @@ public class AbpIdentityEntityFrameworkCoreModule : AbpModule options.AddRepository(); options.AddRepository(); options.AddRepository(); - options.AddRepository(); + options.AddRepository(); options.AddRepository(); options.AddRepository(); + options.AddRepository(); }); } } diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EFCoreIdentitySecurityLogRepository.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentitySecurityLogRepository.cs similarity index 96% rename from modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EFCoreIdentitySecurityLogRepository.cs rename to modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentitySecurityLogRepository.cs index 0e5c2a9b4c..2043293395 100644 --- a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EFCoreIdentitySecurityLogRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentitySecurityLogRepository.cs @@ -10,9 +10,9 @@ using Volo.Abp.EntityFrameworkCore; namespace Volo.Abp.Identity.EntityFrameworkCore; -public class EFCoreIdentitySecurityLogRepository : EfCoreRepository, IIdentitySecurityLogRepository +public class EfCoreIdentitySecurityLogRepository : EfCoreRepository, IIdentitySecurityLogRepository { - public EFCoreIdentitySecurityLogRepository(IDbContextProvider dbContextProvider) + public EfCoreIdentitySecurityLogRepository(IDbContextProvider dbContextProvider) : base(dbContextProvider) { @@ -20,7 +20,7 @@ public class EFCoreIdentitySecurityLogRepository : EfCoreRepository> GetListAsync( string sorting = null, - int maxResultCount = 50, + int maxResultCount = int.MaxValue, int skipCount = 0, DateTime? startTime = null, DateTime? endTime = null, diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentitySessionRepository.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentitySessionRepository.cs new file mode 100644 index 0000000000..222ecf5886 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentitySessionRepository.cs @@ -0,0 +1,85 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Dynamic.Core; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Volo.Abp.Domain.Entities; +using Volo.Abp.Domain.Repositories.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.Timing; + +namespace Volo.Abp.Identity.EntityFrameworkCore; + +public class EfCoreIdentitySessionRepository : EfCoreRepository, IIdentitySessionRepository +{ + public EfCoreIdentitySessionRepository(IDbContextProvider dbContextProvider) + : base(dbContextProvider) + { + + } + + public virtual async Task FindAsync(string sessionId, CancellationToken cancellationToken = default) + { + return await (await GetDbSetAsync()).FirstOrDefaultAsync(x => x.SessionId == sessionId, GetCancellationToken(cancellationToken)); + } + + public virtual async Task GetAsync(string sessionId, CancellationToken cancellationToken = default) + { + var session = await FindAsync(sessionId, cancellationToken); + if (session == null) + { + throw new EntityNotFoundException(typeof(IdentitySession)); + } + + return session; + } + + public virtual async Task> GetListAsync( + string sorting = null, + int maxResultCount = int.MaxValue, + int skipCount = 0, + Guid? userId = null, + string device = null, + string clientId = null, + CancellationToken cancellationToken = default) + { + return await (await GetDbSetAsync()) + .WhereIf(userId.HasValue, x => x.UserId == userId) + .WhereIf(!device.IsNullOrWhiteSpace(), x => x.Device == device) + .WhereIf(!clientId.IsNullOrWhiteSpace(), x => x.ClientId == clientId) + .OrderBy(sorting.IsNullOrWhiteSpace() ? $"{nameof(IdentitySession.LastAccessed)} desc" : sorting) + .PageBy(skipCount, maxResultCount) + .ToListAsync(GetCancellationToken(cancellationToken)); + } + + public virtual async Task GetCountAsync( + Guid? userId = null, + string device = null, + string clientId = null, + CancellationToken cancellationToken = default) + { + return await (await GetDbSetAsync()) + .WhereIf(userId.HasValue, x => x.UserId == userId) + .WhereIf(!device.IsNullOrWhiteSpace(), x => x.Device == device) + .WhereIf(!clientId.IsNullOrWhiteSpace(), x => x.ClientId == clientId) + .LongCountAsync(GetCancellationToken(cancellationToken)); + } + + public virtual async Task DeleteAllAsync(Guid userId, Guid? exceptSessionId = null, CancellationToken cancellationToken = default) + { + await DeleteAsync(x => x.UserId == userId && x.Id != exceptSessionId, cancellationToken: cancellationToken); + } + + public virtual async Task DeleteAllAsync(Guid userId, string device, Guid? exceptSessionId = null, CancellationToken cancellationToken = default) + { + await DeleteAsync(x => x.UserId == userId && x.Device == device && x.Id != exceptSessionId, cancellationToken: cancellationToken); + } + + public virtual async Task DeleteAllAsync(TimeSpan inactiveTimeSpan, CancellationToken cancellationToken = default) + { + var now = LazyServiceProvider.LazyGetRequiredService().Now; + await DeleteDirectAsync(x => x.LastAccessed == null || x.LastAccessed < now.Subtract(inactiveTimeSpan), cancellationToken: cancellationToken); + } +} diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IIdentityDbContext.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IIdentityDbContext.cs index 2f409a61b2..6fe3b8dd9b 100644 --- a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IIdentityDbContext.cs +++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IIdentityDbContext.cs @@ -20,4 +20,6 @@ public interface IIdentityDbContext : IEfCoreDbContext DbSet LinkUsers { get; } DbSet UserDelegations { get; } + + DbSet Sessions { get; } } diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContext.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContext.cs index 79adece5e1..3bb7777cb4 100644 --- a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContext.cs +++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContext.cs @@ -24,6 +24,8 @@ public class IdentityDbContext : AbpDbContext, IIdentityDbCon public DbSet UserDelegations { get; set; } + public DbSet Sessions { get; set; } + public IdentityDbContext(DbContextOptions options) : base(options) { diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContextModelBuilderExtensions.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContextModelBuilderExtensions.cs index f85f72e84e..f94f4690cc 100644 --- a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContextModelBuilderExtensions.cs +++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContextModelBuilderExtensions.cs @@ -279,6 +279,25 @@ public static class IdentityDbContextModelBuilderExtensions b.ApplyObjectExtensionMappings(); }); + builder.Entity(b => + { + b.ToTable(AbpIdentityDbProperties.DbTablePrefix + "Sessions", AbpIdentityDbProperties.DbSchema); + + b.ConfigureByConvention(); + + b.Property(x => x.SessionId).HasMaxLength(IdentitySessionConsts.MaxSessionIdLength).IsRequired(); + b.Property(x => x.Device).HasMaxLength(IdentitySessionConsts.MaxDeviceLength).IsRequired(); + b.Property(x => x.DeviceInfo).HasMaxLength(IdentitySessionConsts.MaxDeviceInfoLength); + b.Property(x => x.ClientId).HasMaxLength(IdentitySessionConsts.MaxClientIdLength); + b.Property(x => x.IpAddresses).HasMaxLength(IdentitySessionConsts.MaxIpAddressesLength); + + b.HasIndex(x => x.SessionId); + b.HasIndex(x => x.Device ); + b.HasIndex(x => new { x.TenantId, x.UserId }); + + b.ApplyObjectExtensionMappings(); + }); + builder.TryConfigureObjectExtensions(); } } diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbContext.cs b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbContext.cs index 90118a534e..86995f5472 100644 --- a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbContext.cs +++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbContext.cs @@ -21,6 +21,8 @@ public class AbpIdentityMongoDbContext : AbpMongoDbContext, IAbpIdentityMongoDbC public IMongoCollection UserDelegations => Collection(); + public IMongoCollection Sessions => Collection(); + protected override void CreateModel(IMongoModelBuilder modelBuilder) { base.CreateModel(modelBuilder); diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbContextExtensions.cs b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbContextExtensions.cs index 5ee7ffc47e..4ccb9fe7f7 100644 --- a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbContextExtensions.cs +++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbContextExtensions.cs @@ -42,5 +42,10 @@ public static class AbpIdentityMongoDbContextExtensions { b.CollectionName = AbpIdentityDbProperties.DbTablePrefix + "UserDelegations"; }); + + builder.Entity(b => + { + b.CollectionName = AbpIdentityDbProperties.DbTablePrefix + "Sessions"; + }); } } diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbModule.cs b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbModule.cs index 35c81b25bb..8537bf630f 100644 --- a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbModule.cs +++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbModule.cs @@ -21,6 +21,7 @@ public class AbpIdentityMongoDbModule : AbpModule options.AddRepository(); options.AddRepository(); options.AddRepository(); + options.AddRepository(); }); } } diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/IAbpIdentityMongoDbContext.cs b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/IAbpIdentityMongoDbContext.cs index 39bcc23b50..7481afe5ac 100644 --- a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/IAbpIdentityMongoDbContext.cs +++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/IAbpIdentityMongoDbContext.cs @@ -20,4 +20,6 @@ public interface IAbpIdentityMongoDbContext : IAbpMongoDbContext IMongoCollection LinkUsers { get; } IMongoCollection UserDelegations { get; } + + IMongoCollection Sessions { get; } } diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentitySecurityLogRepository.cs b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentitySecurityLogRepository.cs index de5587d8d9..6a875444f9 100644 --- a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentitySecurityLogRepository.cs +++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentitySecurityLogRepository.cs @@ -21,7 +21,7 @@ public class MongoIdentitySecurityLogRepository : public virtual async Task> GetListAsync( string sorting = null, - int maxResultCount = 50, + int maxResultCount = int.MaxValue, int skipCount = 0, DateTime? startTime = null, DateTime? endTime = null, diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentitySessionRepository.cs b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentitySessionRepository.cs new file mode 100644 index 0000000000..957699d4d7 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentitySessionRepository.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Dynamic.Core; +using System.Threading; +using System.Threading.Tasks; +using MongoDB.Driver; +using MongoDB.Driver.Linq; +using Volo.Abp.Domain.Entities; +using Volo.Abp.Domain.Repositories.MongoDB; +using Volo.Abp.MongoDB; +using Volo.Abp.Timing; + +namespace Volo.Abp.Identity.MongoDB; + +public class MongoIdentitySessionRepository : MongoDbRepository, IIdentitySessionRepository +{ + public MongoIdentitySessionRepository(IMongoDbContextProvider dbContextProvider) + : base(dbContextProvider) + { + + } + + public virtual async Task FindAsync(string sessionId, CancellationToken cancellationToken = default) + { + return await (await GetMongoQueryableAsync(GetCancellationToken(cancellationToken))) + .As>() + .FirstOrDefaultAsync(x => x.SessionId == sessionId, GetCancellationToken(cancellationToken)); + } + + public virtual async Task GetAsync(string sessionId, CancellationToken cancellationToken = default) + { + var session = await FindAsync(sessionId, cancellationToken); + if (session == null) + { + throw new EntityNotFoundException(typeof(IdentitySession)); + } + + return session; + } + + public virtual async Task> GetListAsync( + string sorting = null, + int maxResultCount = int.MaxValue, + int skipCount = 0, + Guid? userId = null, + string device = null, + string clientId = null, + CancellationToken cancellationToken = default) + { + return await (await GetMongoQueryableAsync(GetCancellationToken(cancellationToken))) + .WhereIf(userId.HasValue, x => x.UserId == userId) + .WhereIf(!device.IsNullOrWhiteSpace(), x => x.Device == device) + .WhereIf(!clientId.IsNullOrWhiteSpace(), x => x.ClientId == clientId) + .OrderBy(sorting.IsNullOrWhiteSpace() ? $"{nameof(IdentitySession.LastAccessed)} desc" : sorting) + .PageBy(skipCount, maxResultCount) + .As>() + .ToListAsync(GetCancellationToken(cancellationToken)); + } + + public virtual async Task GetCountAsync( + Guid? userId = null, + string device = null, + string clientId = null, + CancellationToken cancellationToken = default) + { + return await (await GetMongoQueryableAsync(GetCancellationToken(cancellationToken))) + .WhereIf(userId.HasValue, x => x.UserId == userId) + .WhereIf(!device.IsNullOrWhiteSpace(), x => x.Device == device) + .WhereIf(!clientId.IsNullOrWhiteSpace(), x => x.ClientId == clientId) + .As>() + .LongCountAsync(GetCancellationToken(cancellationToken)); + } + + public virtual async Task DeleteAllAsync(Guid userId, Guid? exceptSessionId = null, CancellationToken cancellationToken = default) + { + await DeleteAsync(x => x.UserId == userId && x.Id != exceptSessionId, cancellationToken: cancellationToken); + } + + public virtual async Task DeleteAllAsync(Guid userId, string device, Guid? exceptSessionId = null, CancellationToken cancellationToken = default) + { + await DeleteAsync(x => x.UserId == userId && x.Device == device && x.Id != exceptSessionId, cancellationToken: cancellationToken); + } + + public virtual async Task DeleteAllAsync(TimeSpan inactiveTimeSpan, CancellationToken cancellationToken = default) + { + var now = LazyServiceProvider.LazyGetRequiredService().Now; + await DeleteDirectAsync(x => x.LastAccessed == null || x.LastAccessed < now.Subtract(inactiveTimeSpan), cancellationToken: cancellationToken); + } +} diff --git a/modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Claims/AbpDefaultOpenIddictClaimsPrincipalHandler.cs b/modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Claims/AbpDefaultOpenIddictClaimsPrincipalHandler.cs index 7a5b3d2835..370b23a856 100644 --- a/modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Claims/AbpDefaultOpenIddictClaimsPrincipalHandler.cs +++ b/modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Claims/AbpDefaultOpenIddictClaimsPrincipalHandler.cs @@ -26,6 +26,12 @@ public class AbpDefaultOpenIddictClaimsPrincipalHandler : IAbpOpenIddictClaimsPr continue; } + if (claim.Type == AbpClaimTypes.SessionId) + { + claim.SetDestinations(OpenIddictConstants.Destinations.AccessToken, OpenIddictConstants.Destinations.IdentityToken); + continue; + } + switch (claim.Type) { case OpenIddictConstants.Claims.PreferredUsername: diff --git a/npm/ng-packs/packages/account-core/ng-package.json b/npm/ng-packs/packages/account-core/ng-package.json index eb13bc988b..488e7eb9a5 100644 --- a/npm/ng-packs/packages/account-core/ng-package.json +++ b/npm/ng-packs/packages/account-core/ng-package.json @@ -3,5 +3,9 @@ "dest": "../../dist/packages/account-core", "lib": { "entryFile": "src/public-api.ts" - } + }, + "allowedNonPeerDependencies": [ + "@abp/ng.core", + "@abp/ng.theme.shared" + ] } diff --git a/npm/ng-packs/packages/account-core/package.json b/npm/ng-packs/packages/account-core/package.json index 566ad031c7..9211212d5f 100644 --- a/npm/ng-packs/packages/account-core/package.json +++ b/npm/ng-packs/packages/account-core/package.json @@ -6,13 +6,9 @@ "type": "git", "url": "https://github.com/abpframework/abp.git" }, - "peerDependencies": { + "dependencies": { "@abp/ng.core": "~8.1.0-rc.3", "@abp/ng.theme.shared": "~8.1.0-rc.3", - "@angular/common": ">=12.0.0", - "@angular/core": ">=12.0.0" - }, - "dependencies": { "tslib": "^2.0.0" }, "publishConfig": { diff --git a/npm/ng-packs/packages/account/src/lib/components/personal-settings/personal-settings.component.ts b/npm/ng-packs/packages/account/src/lib/components/personal-settings/personal-settings.component.ts index 94c96e1e80..8a3a63d376 100644 --- a/npm/ng-packs/packages/account/src/lib/components/personal-settings/personal-settings.component.ts +++ b/npm/ng-packs/packages/account/src/lib/components/personal-settings/personal-settings.component.ts @@ -1,6 +1,6 @@ import { ProfileDto, ProfileService } from '@abp/ng.account.core/proxy'; import { Confirmation, ConfirmationService, ToasterService } from '@abp/ng.theme.shared'; -import { Component, Inject, Injector, OnInit, ViewEncapsulation } from '@angular/core'; +import { Component, inject, Injector, OnInit } from '@angular/core'; import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; import { finalize, filter } from 'rxjs/operators'; import { Account } from '../../models/account'; @@ -31,25 +31,24 @@ export class PersonalSettingsComponent Account.PersonalSettingsComponentInputs, Account.PersonalSettingsComponentOutputs { + private readonly fb = inject(UntypedFormBuilder); + protected readonly toasterService = inject(ToasterService); + protected readonly profileService = inject(ProfileService); + protected readonly manageProfileState = inject(ManageProfileStateService); + protected readonly authService = inject(AuthService); + protected readonly confirmationService = inject(ConfirmationService); + protected readonly configState = inject(ConfigStateService); + protected readonly isPersonalSettingsChangedConfirmationActive = inject( + RE_LOGIN_CONFIRMATION_TOKEN, + ); + private readonly injector = inject(Injector); + selected?: ProfileDto; form!: UntypedFormGroup; inProgress?: boolean; - constructor( - private fb: UntypedFormBuilder, - private toasterService: ToasterService, - private profileService: ProfileService, - private manageProfileState: ManageProfileStateService, - private readonly authService: AuthService, - private confirmationService: ConfirmationService, - private configState: ConfigStateService, - @Inject(RE_LOGIN_CONFIRMATION_TOKEN) - private isPersonalSettingsChangedConfirmationActive: boolean, - protected injector: Injector, - ) {} - buildForm() { this.selected = this.manageProfileState.getProfile(); if (!this.selected) { @@ -76,10 +75,10 @@ export class PersonalSettingsComponent this.configState.refreshAppState(); this.toasterService.success('AbpAccount::PersonalSettingsSaved', 'Success', { life: 5000 }); - if(isRefreshTokenExists){ + if (isRefreshTokenExists) { return this.authService.refreshToken(); } - + if (isLogOutConfirmMessageVisible) { this.showLogoutConfirmMessage(); } diff --git a/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.html b/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.html index cfa1b912f2..5b28627085 100644 --- a/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.html +++ b/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.html @@ -3,8 +3,6 @@ [rows]="data" [count]="recordsTotal" [list]="list" - [offset]="list?.page" - (page)="setPage($event)" (activate)="tableActivate.emit($event)" > @if (actionsTemplate || (actionList.length && hasAtLeastOnePermittedAction)) { diff --git a/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts b/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts index a65a3925b1..0018f90985 100644 --- a/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts +++ b/npm/ng-packs/packages/components/extensible/src/lib/components/extensible-table/extensible-table.component.ts @@ -1,20 +1,3 @@ -import { - ABP, - ConfigStateService, - getShortDateFormat, - getShortDateShortTimeFormat, - getShortTimeFormat, - ListService, - LocalizationModule, - PermissionDirective, - PermissionService, -} from '@abp/ng.core'; -import { - AsyncPipe, - formatDate, - NgComponentOutlet, - NgTemplateOutlet, -} from '@angular/common'; import { ChangeDetectionStrategy, Component, @@ -29,8 +12,31 @@ import { TemplateRef, TrackByFunction, } from '@angular/core'; +import { AsyncPipe, formatDate, NgComponentOutlet, NgTemplateOutlet } from '@angular/common'; + import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; + +import { NgbTooltip } from '@ng-bootstrap/ng-bootstrap'; +import { NgxDatatableModule } from '@swimlane/ngx-datatable'; + +import { + ABP, + ConfigStateService, + getShortDateFormat, + getShortDateShortTimeFormat, + getShortTimeFormat, + ListService, + LocalizationModule, + PermissionDirective, + PermissionService, +} from '@abp/ng.core'; +import { + AbpVisibleDirective, + NgxDatatableDefaultDirective, + NgxDatatableListDirective, +} from '@abp/ng.theme.shared'; + import { ePropType } from '../../enums/props.enum'; import { EntityActionList } from '../../models/entity-actions'; import { EntityProp, EntityPropList } from '../../models/entity-props'; @@ -41,14 +47,7 @@ import { EXTENSIONS_IDENTIFIER, PROP_DATA_STREAM, } from '../../tokens/extensions.token'; -import { NgxDatatableModule } from '@swimlane/ngx-datatable'; import { GridActionsComponent } from '../grid-actions/grid-actions.component'; -import { NgbTooltip } from '@ng-bootstrap/ng-bootstrap'; -import { - AbpVisibleDirective, - NgxDatatableDefaultDirective, - NgxDatatableListDirective, -} from '@abp/ng.theme.shared'; const DEFAULT_ACTIONS_COLUMN_WIDTH = 150; @@ -172,32 +171,7 @@ export class ExtensibleTableComponent implements OnChanges { ); } - setPage({ offset }) { - this.list.page = offset; - } - - ngOnChanges({ data, recordsTotal }: SimpleChanges) { - if (data?.currentValue.length < 1 && recordsTotal?.currentValue > 0) { - let maxPage = Math.floor(Number(recordsTotal?.currentValue / this.list.maxResultCount)); - - if(recordsTotal?.currentValue < this.list.maxResultCount) { - this.list.page = 0; - return; - } - - if (recordsTotal?.currentValue % this.list.maxResultCount === 0) { - maxPage -= 1; - } - - if (this.list.page < maxPage) { - this.list.page = this.list.page; - return; - } - - this.list.page = maxPage; - return; - } - + ngOnChanges({ data }: SimpleChanges) { if (!data?.currentValue) return; if (data.currentValue.length < 1) { diff --git a/npm/ng-packs/packages/feature-management/src/lib/components/feature-management/feature-management.component.ts b/npm/ng-packs/packages/feature-management/src/lib/components/feature-management/feature-management.component.ts index 25d8e76764..2dd2497e81 100644 --- a/npm/ng-packs/packages/feature-management/src/lib/components/feature-management/feature-management.component.ts +++ b/npm/ng-packs/packages/feature-management/src/lib/components/feature-management/feature-management.component.ts @@ -11,7 +11,7 @@ import { LocaleDirection, ToasterService, } from '@abp/ng.theme.shared'; -import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { Component, EventEmitter, Input, Output, inject } from '@angular/core'; import { finalize } from 'rxjs/operators'; import { FeatureManagement } from '../../models/feature-management'; @@ -31,6 +31,12 @@ export class FeatureManagementComponent FeatureManagement.FeatureManagementComponentInputs, FeatureManagement.FeatureManagementComponentOutputs { + protected readonly track = inject(TrackByService); + protected readonly toasterService = inject(ToasterService); + protected readonly service = inject(FeaturesService); + protected readonly configState = inject(ConfigStateService); + protected readonly confirmationService = inject(ConfirmationService); + @Input() providerKey: string; @@ -72,14 +78,6 @@ export class FeatureManagementComponent modalBusy = false; - constructor( - public readonly track: TrackByService, - private toasterService: ToasterService, - protected service: FeaturesService, - protected configState: ConfigStateService, - protected confirmationService: ConfirmationService, - ) {} - openModal() { if (!this.providerName) { throw new Error('providerName is required.'); @@ -127,6 +125,7 @@ export class FeatureManagementComponent .subscribe(() => { this.visible = false; + this.toasterService.success('AbpFeatureManagement::Saved'); if (!this.providerKey) { // to refresh host's features this.configState.refreshAppState().subscribe(); diff --git a/npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.ts b/npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.ts index fd8b3670f8..794b545fcd 100644 --- a/npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.ts +++ b/npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.ts @@ -1,13 +1,13 @@ import { ListService, PagedAndSortedResultRequestDto, PagedResultDto } from '@abp/ng.core'; import { IdentityRoleDto, IdentityRoleService } from '@abp/ng.identity/proxy'; import { ePermissionManagementComponents } from '@abp/ng.permission-management'; -import {Confirmation, ConfirmationService, ToasterService} from '@abp/ng.theme.shared'; +import { Confirmation, ConfirmationService, ToasterService } from '@abp/ng.theme.shared'; import { EXTENSIONS_IDENTIFIER, FormPropData, generateFormFromProps, } from '@abp/ng.components/extensible'; -import { Component, Injector, OnInit } from '@angular/core'; +import { Component, inject, Injector, OnInit } from '@angular/core'; import { UntypedFormGroup } from '@angular/forms'; import { finalize } from 'rxjs/operators'; import { eIdentityComponents } from '../../enums/components'; @@ -24,6 +24,12 @@ import { eIdentityComponents } from '../../enums/components'; ], }) export class RolesComponent implements OnInit { + protected readonly list = inject(ListService); + protected readonly confirmationService = inject(ConfirmationService); + protected readonly toasterService = inject(ToasterService); + private readonly injector = inject(Injector); + protected readonly service = inject(IdentityRoleService); + data: PagedResultDto = { items: [], totalCount: 0 }; form!: UntypedFormGroup; @@ -44,14 +50,6 @@ export class RolesComponent implements OnInit { this.visiblePermissions = event; }; - constructor( - public readonly list: ListService, - protected confirmationService: ConfirmationService, - private toasterService: ToasterService, - protected injector: Injector, - protected service: IdentityRoleService, - ) {} - ngOnInit() { this.hookToQuery(); } @@ -90,6 +88,7 @@ export class RolesComponent implements OnInit { .pipe(finalize(() => (this.modalBusy = false))) .subscribe(() => { this.isModalVisible = false; + this.toasterService.success('AbpUi::SavedSuccessfully'); this.list.get(); }); } @@ -101,7 +100,7 @@ export class RolesComponent implements OnInit { }) .subscribe((status: Confirmation.Status) => { if (status === Confirmation.Status.confirm) { - this.toasterService.success('AbpUi::SuccessfullyDeleted'); + this.toasterService.success('AbpUi::DeletedSuccessfully'); this.service.delete(id).subscribe(() => this.list.get()); } }); diff --git a/npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts b/npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts index f8802de304..a0f0e08e4b 100644 --- a/npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts +++ b/npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts @@ -6,7 +6,12 @@ import { IdentityUserService, } from '@abp/ng.identity/proxy'; import { ePermissionManagementComponents } from '@abp/ng.permission-management'; -import {Confirmation, ConfirmationService, eFormComponets, ToasterService} from '@abp/ng.theme.shared'; +import { + Confirmation, + ConfirmationService, + eFormComponets, + ToasterService, +} from '@abp/ng.theme.shared'; import { EXTENSIONS_IDENTIFIER, FormPropData, @@ -14,13 +19,19 @@ import { } from '@abp/ng.components/extensible'; import { Component, + inject, Injector, OnInit, TemplateRef, TrackByFunction, ViewChild, } from '@angular/core'; -import { AbstractControl, UntypedFormArray, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; +import { + AbstractControl, + UntypedFormArray, + UntypedFormBuilder, + UntypedFormGroup, +} from '@angular/forms'; import { finalize, switchMap, tap } from 'rxjs/operators'; import { eIdentityComponents } from '../../enums/components'; @@ -36,6 +47,13 @@ import { eIdentityComponents } from '../../enums/components'; ], }) export class UsersComponent implements OnInit { + protected readonly list = inject(ListService); + protected readonly confirmationService = inject(ConfirmationService); + protected readonly service = inject(IdentityUserService); + protected readonly toasterService = inject(ToasterService); + private readonly fb = inject(UntypedFormBuilder); + private readonly injector = inject(Injector); + data: PagedResultDto = { items: [], totalCount: 0 }; @ViewChild('modalContent', { static: false }) @@ -61,7 +79,7 @@ export class UsersComponent implements OnInit { entityDisplayName: string; - inputKey=eFormComponets.FormCheckboxComponent + inputKey = eFormComponets.FormCheckboxComponent; trackByFn: TrackByFunction = (index, item) => Object.keys(item)[0] || index; @@ -73,15 +91,6 @@ export class UsersComponent implements OnInit { return ((this.form.get('roleNames') as UntypedFormArray)?.controls as UntypedFormGroup[]) || []; } - constructor( - public readonly list: ListService, - protected confirmationService: ConfirmationService, - protected service: IdentityUserService, - private toasterService: ToasterService, - protected fb: UntypedFormBuilder, - protected injector: Injector, - ) {} - ngOnInit() { this.hookToQuery(); } @@ -158,6 +167,7 @@ export class UsersComponent implements OnInit { .pipe(finalize(() => (this.modalBusy = false))) .subscribe(() => { this.isModalVisible = false; + this.toasterService.success('AbpUi::SavedSuccessfully'); this.list.get(); }); } @@ -170,7 +180,7 @@ export class UsersComponent implements OnInit { .subscribe((status: Confirmation.Status) => { if (status === Confirmation.Status.confirm) { this.service.delete(id).subscribe(() => { - this.toasterService.success('AbpUi::SuccessfullyDeleted'); + this.toasterService.success('AbpUi::DeletedSuccessfully'); this.list.get(); }); } diff --git a/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.ts b/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.ts index 4cb90a0fff..8503a2bd81 100644 --- a/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.ts +++ b/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.ts @@ -7,11 +7,12 @@ import { ProviderInfoDto, UpdatePermissionDto, } from '@abp/ng.permission-management/proxy'; -import { LocaleDirection } from '@abp/ng.theme.shared'; +import { LocaleDirection, ToasterService } from '@abp/ng.theme.shared'; import { Component, ElementRef, EventEmitter, + inject, Input, Output, QueryList, @@ -41,16 +42,21 @@ type PermissionWithGroupName = PermissionGrantInfoDto & { overflow-y: scroll; } .scroll-in-modal { - overflow:auto; - max-height: calc(100vh - 15rem) + overflow: auto; + max-height: calc(100vh - 15rem); } `, ], }) export class PermissionManagementComponent implements - PermissionManagement.PermissionManagementComponentInputs, - PermissionManagement.PermissionManagementComponentOutputs { + PermissionManagement.PermissionManagementComponentInputs, + PermissionManagement.PermissionManagementComponentOutputs +{ + protected readonly service = inject(PermissionsService); + protected readonly configState = inject(ConfigStateService); + protected readonly toasterService = inject(ToasterService); + @Input() readonly providerName!: string; @@ -117,8 +123,6 @@ export class PermissionManagementComponent trackByFn: TrackByFunction = (_, item) => item.name; - constructor(protected service: PermissionsService, protected configState: ConfigStateService) { } - getChecked(name: string) { return (this.permissions.find(per => per.name === name) || { isGranted: false }).isGranted; } @@ -130,19 +134,20 @@ export class PermissionManagementComponent return; } - const margin = `margin-${(document.body.dir as LocaleDirection) === 'rtl' ? 'right' : 'left' - }.px`; + const margin = `margin-${ + (document.body.dir as LocaleDirection) === 'rtl' ? 'right' : 'left' + }.px`; const permissions = (this.data.groups.find(group => group.name === this.selectedGroup?.name) || {}).permissions || []; this.selectedGroupPermissions = permissions.map( permission => - ({ - ...permission, - style: { [margin]: findMargin(permissions, permission) }, - isGranted: (this.permissions.find(per => per.name === permission.name) || {}).isGranted, - } as unknown as PermissionWithStyle), + ({ + ...permission, + style: { [margin]: findMargin(permissions, permission) }, + isGranted: (this.permissions.find(per => per.name === permission.name) || {}).isGranted, + }) as unknown as PermissionWithStyle, ); } @@ -199,19 +204,19 @@ export class PermissionManagementComponent if (per.name === clickedPermissions.parentName) { parentPermission = per; } - }) + }); this.permissions.forEach(per => { if (parentPermission.name === per.parentName) { per.isGranted && childPermissionGrantedCount++; } - }) + }); if (childPermissionGrantedCount === 1 && !parentPermission.isGranted) { this.permissions = this.permissions.map(per => { if (per.name === parentPermission.name) { per.isGranted = true; } return per; - }) + }); } return; } @@ -220,16 +225,16 @@ export class PermissionManagementComponent per.isGranted = false; } return per; - }) + }); } updateSelectedGroupPermissions(clickedPermissions: PermissionGrantInfoDto) { this.selectedGroupPermissions = this.selectedGroupPermissions.map(per => { if (per.name === clickedPermissions.name) { - per.isGranted = !per.isGranted + per.isGranted = !per.isGranted; } return per; - }) + }); } setTabCheckboxState() { @@ -310,7 +315,7 @@ export class PermissionManagementComponent const changedPermissions: UpdatePermissionDto[] = this.permissions .filter(per => (unchangedPermissions.find(unchanged => unchanged.name === per.name) || {}).isGranted === - per.isGranted + per.isGranted ? false : true, ) @@ -332,6 +337,7 @@ export class PermissionManagementComponent ) .subscribe(() => { this.visible = false; + this.toasterService.success('AbpUi::SavedSuccessfully'); }); } diff --git a/npm/ng-packs/packages/tenant-management/src/lib/components/tenants/tenants.component.ts b/npm/ng-packs/packages/tenant-management/src/lib/components/tenants/tenants.component.ts index b759947b32..99169b1cbe 100644 --- a/npm/ng-packs/packages/tenant-management/src/lib/components/tenants/tenants.component.ts +++ b/npm/ng-packs/packages/tenant-management/src/lib/components/tenants/tenants.component.ts @@ -1,13 +1,13 @@ import { ListService, PagedResultDto } from '@abp/ng.core'; import { eFeatureManagementComponents } from '@abp/ng.feature-management'; import { GetTenantsInput, TenantDto, TenantService } from '@abp/ng.tenant-management/proxy'; -import {Confirmation, ConfirmationService, ToasterService} from '@abp/ng.theme.shared'; +import { Confirmation, ConfirmationService, ToasterService } from '@abp/ng.theme.shared'; import { EXTENSIONS_IDENTIFIER, FormPropData, generateFormFromProps, } from '@abp/ng.components/extensible'; -import { Component, Injector, OnInit } from '@angular/core'; +import { Component, inject, Injector, OnInit } from '@angular/core'; import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; import { finalize } from 'rxjs/operators'; import { eTenantManagementComponents } from '../../enums/components'; @@ -24,6 +24,13 @@ import { eTenantManagementComponents } from '../../enums/components'; ], }) export class TenantsComponent implements OnInit { + protected readonly list = inject(ListService); + protected readonly confirmationService = inject(ConfirmationService); + protected readonly service = inject(TenantService); + protected readonly toasterService = inject(ToasterService); + private readonly fb = inject(UntypedFormBuilder); + private readonly injector = inject(Injector); + data: PagedResultDto = { items: [], totalCount: 0 }; selected!: TenantDto; @@ -48,15 +55,6 @@ export class TenantsComponent implements OnInit { this.visibleFeatures = value; }; - constructor( - public readonly list: ListService, - private injector: Injector, - private confirmationService: ConfirmationService, - private service: TenantService, - private toasterService: ToasterService, - private fb: UntypedFormBuilder, - ) {} - ngOnInit() { this.hookToQuery(); } @@ -93,6 +91,7 @@ export class TenantsComponent implements OnInit { .pipe(finalize(() => (this.modalBusy = false))) .subscribe(() => { this.isModalVisible = false; + this.toasterService.success('AbpUi::SavedSuccessfully'); this.list.get(); }); } @@ -108,7 +107,7 @@ export class TenantsComponent implements OnInit { ) .subscribe((status: Confirmation.Status) => { if (status === Confirmation.Status.confirm) { - this.toasterService.success('AbpUi::SuccessfullyDeleted'); + this.toasterService.success('AbpUi::DeletedSuccessfully'); this.service.delete(id).subscribe(() => this.list.get()); } }); diff --git a/npm/ng-packs/packages/theme-shared/src/lib/directives/ngx-datatable-list.directive.ts b/npm/ng-packs/packages/theme-shared/src/lib/directives/ngx-datatable-list.directive.ts index 3769a3aa3d..577af2bd9c 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/directives/ngx-datatable-list.directive.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/directives/ngx-datatable-list.directive.ts @@ -1,20 +1,19 @@ -import { ListService, LocalizationService } from '@abp/ng.core'; import { ChangeDetectorRef, Directive, - Inject, Input, OnChanges, - OnDestroy, OnInit, - Optional, + DoCheck, SimpleChanges, + inject, + DestroyRef } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { DatatableComponent } from '@swimlane/ngx-datatable'; -import { Subscription } from 'rxjs'; +import { ListService, LocalizationService } from '@abp/ng.core'; import { defaultNgxDatatableMessages, - NgxDatatableMessages, NGX_DATATABLE_MESSAGES, } from '../tokens/ngx-datatable-messages.token'; @@ -24,22 +23,39 @@ import { standalone: true, exportAs: 'ngxDatatableList', }) -export class NgxDatatableListDirective implements OnChanges, OnDestroy, OnInit { - private subscription = new Subscription(); - private querySubscription = new Subscription(); - +export class NgxDatatableListDirective implements OnChanges, OnInit, DoCheck { @Input() list!: ListService; - constructor( - private table: DatatableComponent, - private cdRef: ChangeDetectorRef, - private localizationService: LocalizationService, - @Optional() @Inject(NGX_DATATABLE_MESSAGES) private ngxDatatableMessages: NgxDatatableMessages, - ) { + protected readonly table = inject(DatatableComponent); + protected readonly cdRef = inject(ChangeDetectorRef); + protected readonly destroyRef = inject(DestroyRef); + protected readonly localizationService = inject(LocalizationService); + protected readonly ngxDatatableMessages = inject(NGX_DATATABLE_MESSAGES, { optional: true }); + + constructor() { this.setInitialValues(); } - private setInitialValues() { + ngDoCheck(): void { + this.refreshPageIfDataExist(); + } + + ngOnInit() { + this.subscribeToPage(); + this.subscribeToSort(); + } + + ngOnChanges({ list }: SimpleChanges) { + this.subscribeToQuery(); + + if (!list.firstChange) return; + + const { maxResultCount, page } = list.currentValue; + this.table.limit = maxResultCount; + this.table.offset = page; + } + + protected setInitialValues() { this.table.externalPaging = true; this.table.externalSorting = true; @@ -53,8 +69,8 @@ export class NgxDatatableListDirective implements OnChanges, OnDestroy, OnInit { }; } - private subscribeToSort() { - const sub = this.table.sort.subscribe(({ sorts: [{ prop, dir }] }) => { + protected subscribeToSort() { + this.table.sort.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(({ sorts: [{ prop, dir }] }) => { if (prop === this.list.sortKey && this.list.sortOrder === 'desc') { this.list.sortKey = ''; this.list.sortOrder = ''; @@ -65,34 +81,45 @@ export class NgxDatatableListDirective implements OnChanges, OnDestroy, OnInit { this.list.sortOrder = dir; } }); - this.subscription.add(sub); } - private subscribeToQuery() { - if (!this.querySubscription.closed) this.querySubscription.unsubscribe(); + protected subscribeToPage() { + this.table.page.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(({ offset }) => { + this.setTablePage(offset); + }); + } - this.querySubscription = this.list.query$.subscribe(() => { + protected subscribeToQuery() { + this.list.query$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => { const offset = this.list.page; if (this.table.offset !== offset) this.table.offset = offset; }); } - ngOnChanges({ list }: SimpleChanges) { - this.subscribeToQuery(); + protected setTablePage(pageNum: number) { + this.list.page = pageNum; + this.table.offset = pageNum; + } - if (!list.firstChange) return; + protected refreshPageIfDataExist() { + if (this.table.rows.length < 1 && this.table.count > 0) { + let maxPage = Math.floor(Number(this.table.count / this.list.maxResultCount)); - const { maxResultCount, page } = list.currentValue; - this.table.limit = maxResultCount; - this.table.offset = page; - } + if (this.table.count < this.list.maxResultCount) { + this.setTablePage(0); + return; + } - ngOnDestroy() { - this.subscription.unsubscribe(); - this.querySubscription.unsubscribe(); - } + if (this.table.count % this.list.maxResultCount === 0) { + maxPage -= 1; + } - ngOnInit() { - this.subscribeToSort(); + if (this.list.page < maxPage) { + this.setTablePage(this.list.page); + return; + } + + this.setTablePage(maxPage); + } } } diff --git a/npm/ng-packs/packages/theme-shared/src/lib/services/create-error-component.service.ts b/npm/ng-packs/packages/theme-shared/src/lib/services/create-error-component.service.ts index 5a6f02aef9..da1ae0ddc0 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/services/create-error-component.service.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/services/create-error-component.service.ts @@ -23,7 +23,7 @@ export class CreateErrorComponentService { protected readonly rendererFactory = inject(RendererFactory2); protected readonly cfRes = inject(ComponentFactoryResolver); protected readonly routerEvents = inject(RouterEvents); - protected readonly injector = inject(Injector); + private readonly injector = inject(Injector); protected readonly httpErrorConfig = inject(HTTP_ERROR_CONFIG); componentRef: ComponentRef | null = null; diff --git a/nupkg/common.ps1 b/nupkg/common.ps1 index 78de2aef44..9f014cd526 100644 --- a/nupkg/common.ps1 +++ b/nupkg/common.ps1 @@ -97,6 +97,7 @@ $projects = ( "framework/src/Volo.Abp.AspNetCore.Authentication.JwtBearer", "framework/src/Volo.Abp.AspNetCore.Authentication.OAuth", "framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect", + "framework/src/Volo.Abp.AspNetCore.Abstractions", "framework/src/Volo.Abp.AspNetCore", "framework/src/Volo.Abp.AspNetCore.Mvc.Dapr", "framework/src/Volo.Abp.AspNetCore.Mvc.Dapr.EventBus", diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20240125061235_Initial.Designer.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20240312033651_Initial.Designer.cs similarity index 97% rename from templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20240125061235_Initial.Designer.cs rename to templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20240312033651_Initial.Designer.cs index 2f3a437364..b97eb71e95 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20240125061235_Initial.Designer.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20240312033651_Initial.Designer.cs @@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore; namespace MyCompanyName.MyProjectName.Blazor.Server.Migrations { [DbContext(typeof(MyProjectNameDbContext))] - [Migration("20240125061235_Initial")] + [Migration("20240312033651_Initial")] partial class Initial { /// @@ -647,6 +647,58 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Migrations b.ToTable("AbpSecurityLogs", (string)null); }); + modelBuilder.Entity("Volo.Abp.Identity.IdentitySession", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Device") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("DeviceInfo") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("IpAddresses") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("LastAccessed") + .HasColumnType("datetime2"); + + b.Property("SessionId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("SignedIn") + .HasColumnType("datetime2"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("Device"); + + b.HasIndex("SessionId"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AbpSessions", (string)null); + }); + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => { b.Property("Id") diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20240125061235_Initial.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20240312033651_Initial.cs similarity index 96% rename from templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20240125061235_Initial.cs rename to templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20240312033651_Initial.cs index dd96c605e7..39c3b550b9 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20240125061235_Initial.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/20240312033651_Initial.cs @@ -255,6 +255,26 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Migrations table.PrimaryKey("PK_AbpSecurityLogs", x => x.Id); }); + migrationBuilder.CreateTable( + name: "AbpSessions", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + SessionId = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + Device = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + DeviceInfo = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + UserId = table.Column(type: "uniqueidentifier", nullable: false), + ClientId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + IpAddresses = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + SignedIn = table.Column(type: "datetime2", nullable: false), + LastAccessed = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AbpSessions", x => x.Id); + }); + migrationBuilder.CreateTable( name: "AbpSettingDefinitions", columns: table => new @@ -896,6 +916,21 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Migrations table: "AbpSecurityLogs", columns: new[] { "TenantId", "UserId" }); + migrationBuilder.CreateIndex( + name: "IX_AbpSessions_Device", + table: "AbpSessions", + column: "Device"); + + migrationBuilder.CreateIndex( + name: "IX_AbpSessions_SessionId", + table: "AbpSessions", + column: "SessionId"); + + migrationBuilder.CreateIndex( + name: "IX_AbpSessions_TenantId_UserId", + table: "AbpSessions", + columns: new[] { "TenantId", "UserId" }); + migrationBuilder.CreateIndex( name: "IX_AbpSettingDefinitions_Name", table: "AbpSettingDefinitions", @@ -1032,6 +1067,9 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Migrations migrationBuilder.DropTable( name: "AbpSecurityLogs"); + migrationBuilder.DropTable( + name: "AbpSessions"); + migrationBuilder.DropTable( name: "AbpSettingDefinitions"); diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/MyProjectNameDbContextModelSnapshot.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/MyProjectNameDbContextModelSnapshot.cs index 652e7b674d..0a52057acc 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/MyProjectNameDbContextModelSnapshot.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Migrations/MyProjectNameDbContextModelSnapshot.cs @@ -644,6 +644,58 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Migrations b.ToTable("AbpSecurityLogs", (string)null); }); + modelBuilder.Entity("Volo.Abp.Identity.IdentitySession", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Device") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("DeviceInfo") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("IpAddresses") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("LastAccessed") + .HasColumnType("datetime2"); + + b.Property("SessionId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("SignedIn") + .HasColumnType("datetime2"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("Device"); + + b.HasIndex("SessionId"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AbpSessions", (string)null); + }); + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => { b.Property("Id") diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20240125061501_Initial.Designer.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20240312033906_Initial.Designer.cs similarity index 97% rename from templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20240125061501_Initial.Designer.cs rename to templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20240312033906_Initial.Designer.cs index f25d60e99b..84ee9411af 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20240125061501_Initial.Designer.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20240312033906_Initial.Designer.cs @@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore; namespace MyCompanyName.MyProjectName.Migrations { [DbContext(typeof(MyProjectNameDbContext))] - [Migration("20240125061501_Initial")] + [Migration("20240312033906_Initial")] partial class Initial { /// @@ -647,6 +647,58 @@ namespace MyCompanyName.MyProjectName.Migrations b.ToTable("AbpSecurityLogs", (string)null); }); + modelBuilder.Entity("Volo.Abp.Identity.IdentitySession", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Device") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("DeviceInfo") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("IpAddresses") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("LastAccessed") + .HasColumnType("datetime2"); + + b.Property("SessionId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("SignedIn") + .HasColumnType("datetime2"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("Device"); + + b.HasIndex("SessionId"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AbpSessions", (string)null); + }); + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => { b.Property("Id") diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20240125061248_Initial.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20240312033906_Initial.cs similarity index 97% rename from templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20240125061248_Initial.cs rename to templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20240312033906_Initial.cs index 9fc3a5a0b9..a3dbf4a768 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20240125061248_Initial.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20240312033906_Initial.cs @@ -45,27 +45,6 @@ namespace MyCompanyName.MyProjectName.Migrations table.PrimaryKey("PK_AbpAuditLogs", x => x.Id); }); - migrationBuilder.CreateTable( - name: "AbpBackgroundJobs", - columns: table => new - { - Id = table.Column(type: "uniqueidentifier", nullable: false), - JobName = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), - JobArgs = table.Column(type: "nvarchar(max)", maxLength: 1048576, nullable: false), - TryCount = table.Column(type: "smallint", nullable: false, defaultValue: (short)0), - CreationTime = table.Column(type: "datetime2", nullable: false), - NextTryTime = table.Column(type: "datetime2", nullable: false), - LastTryTime = table.Column(type: "datetime2", nullable: true), - IsAbandoned = table.Column(type: "bit", nullable: false, defaultValue: false), - Priority = table.Column(type: "tinyint", nullable: false, defaultValue: (byte)15), - ExtraProperties = table.Column(type: "nvarchar(max)", nullable: false), - ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_AbpBackgroundJobs", x => x.Id); - }); - migrationBuilder.CreateTable( name: "AbpClaimTypes", columns: table => new @@ -276,6 +255,26 @@ namespace MyCompanyName.MyProjectName.Migrations table.PrimaryKey("PK_AbpSecurityLogs", x => x.Id); }); + migrationBuilder.CreateTable( + name: "AbpSessions", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + SessionId = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + Device = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + DeviceInfo = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + UserId = table.Column(type: "uniqueidentifier", nullable: false), + ClientId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + IpAddresses = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + SignedIn = table.Column(type: "datetime2", nullable: false), + LastAccessed = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AbpSessions", x => x.Id); + }); + migrationBuilder.CreateTable( name: "AbpSettingDefinitions", columns: table => new @@ -802,11 +801,6 @@ namespace MyCompanyName.MyProjectName.Migrations table: "AbpAuditLogs", columns: new[] { "TenantId", "UserId", "ExecutionTime" }); - migrationBuilder.CreateIndex( - name: "IX_AbpBackgroundJobs_IsAbandoned_NextTryTime", - table: "AbpBackgroundJobs", - columns: new[] { "IsAbandoned", "NextTryTime" }); - migrationBuilder.CreateIndex( name: "IX_AbpEntityChanges_AuditLogId", table: "AbpEntityChanges", @@ -922,6 +916,21 @@ namespace MyCompanyName.MyProjectName.Migrations table: "AbpSecurityLogs", columns: new[] { "TenantId", "UserId" }); + migrationBuilder.CreateIndex( + name: "IX_AbpSessions_Device", + table: "AbpSessions", + column: "Device"); + + migrationBuilder.CreateIndex( + name: "IX_AbpSessions_SessionId", + table: "AbpSessions", + column: "SessionId"); + + migrationBuilder.CreateIndex( + name: "IX_AbpSessions_TenantId_UserId", + table: "AbpSessions", + columns: new[] { "TenantId", "UserId" }); + migrationBuilder.CreateIndex( name: "IX_AbpSettingDefinitions_Name", table: "AbpSettingDefinitions", @@ -1022,9 +1031,6 @@ namespace MyCompanyName.MyProjectName.Migrations migrationBuilder.DropTable( name: "AbpAuditLogActions"); - migrationBuilder.DropTable( - name: "AbpBackgroundJobs"); - migrationBuilder.DropTable( name: "AbpClaimTypes"); @@ -1061,6 +1067,9 @@ namespace MyCompanyName.MyProjectName.Migrations migrationBuilder.DropTable( name: "AbpSecurityLogs"); + migrationBuilder.DropTable( + name: "AbpSessions"); + migrationBuilder.DropTable( name: "AbpSettingDefinitions"); diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/MyProjectNameDbContextModelSnapshot.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/MyProjectNameDbContextModelSnapshot.cs index 72f44ed239..d74eefbde1 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/MyProjectNameDbContextModelSnapshot.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/MyProjectNameDbContextModelSnapshot.cs @@ -644,6 +644,58 @@ namespace MyCompanyName.MyProjectName.Migrations b.ToTable("AbpSecurityLogs", (string)null); }); + modelBuilder.Entity("Volo.Abp.Identity.IdentitySession", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Device") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("DeviceInfo") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("IpAddresses") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("LastAccessed") + .HasColumnType("datetime2"); + + b.Property("SessionId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("SignedIn") + .HasColumnType("datetime2"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("Device"); + + b.HasIndex("SessionId"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AbpSessions", (string)null); + }); + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => { b.Property("Id") diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20240125061101_Initial.Designer.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20240321011533_Initial.Designer.cs similarity index 97% rename from templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20240125061101_Initial.Designer.cs rename to templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20240321011533_Initial.Designer.cs index 364eaa6b57..309ac9f973 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20240125061101_Initial.Designer.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20240321011533_Initial.Designer.cs @@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore; namespace MyCompanyName.MyProjectName.Host.Migrations { [DbContext(typeof(MyProjectNameDbContext))] - [Migration("20240125061101_Initial")] + [Migration("20240321011533_Initial")] partial class Initial { /// @@ -647,6 +647,58 @@ namespace MyCompanyName.MyProjectName.Host.Migrations b.ToTable("AbpSecurityLogs", (string)null); }); + modelBuilder.Entity("Volo.Abp.Identity.IdentitySession", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Device") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("DeviceInfo") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("IpAddresses") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("LastAccessed") + .HasColumnType("datetime2"); + + b.Property("SessionId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("SignedIn") + .HasColumnType("datetime2"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("Device"); + + b.HasIndex("SessionId"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AbpSessions", (string)null); + }); + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => { b.Property("Id") diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20240125061101_Initial.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20240321011533_Initial.cs similarity index 96% rename from templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20240125061101_Initial.cs rename to templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20240321011533_Initial.cs index bfb34fcaad..e36cf69df7 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20240125061101_Initial.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/20240321011533_Initial.cs @@ -255,6 +255,26 @@ namespace MyCompanyName.MyProjectName.Host.Migrations table.PrimaryKey("PK_AbpSecurityLogs", x => x.Id); }); + migrationBuilder.CreateTable( + name: "AbpSessions", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + SessionId = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + Device = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + DeviceInfo = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + UserId = table.Column(type: "uniqueidentifier", nullable: false), + ClientId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + IpAddresses = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + SignedIn = table.Column(type: "datetime2", nullable: false), + LastAccessed = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AbpSessions", x => x.Id); + }); + migrationBuilder.CreateTable( name: "AbpSettingDefinitions", columns: table => new @@ -896,6 +916,21 @@ namespace MyCompanyName.MyProjectName.Host.Migrations table: "AbpSecurityLogs", columns: new[] { "TenantId", "UserId" }); + migrationBuilder.CreateIndex( + name: "IX_AbpSessions_Device", + table: "AbpSessions", + column: "Device"); + + migrationBuilder.CreateIndex( + name: "IX_AbpSessions_SessionId", + table: "AbpSessions", + column: "SessionId"); + + migrationBuilder.CreateIndex( + name: "IX_AbpSessions_TenantId_UserId", + table: "AbpSessions", + columns: new[] { "TenantId", "UserId" }); + migrationBuilder.CreateIndex( name: "IX_AbpSettingDefinitions_Name", table: "AbpSettingDefinitions", @@ -1032,6 +1067,9 @@ namespace MyCompanyName.MyProjectName.Host.Migrations migrationBuilder.DropTable( name: "AbpSecurityLogs"); + migrationBuilder.DropTable( + name: "AbpSessions"); + migrationBuilder.DropTable( name: "AbpSettingDefinitions"); diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/MyProjectNameDbContextModelSnapshot.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/MyProjectNameDbContextModelSnapshot.cs index f2b46a651f..f2ef0d1071 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/MyProjectNameDbContextModelSnapshot.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Migrations/MyProjectNameDbContextModelSnapshot.cs @@ -644,6 +644,58 @@ namespace MyCompanyName.MyProjectName.Host.Migrations b.ToTable("AbpSecurityLogs", (string)null); }); + modelBuilder.Entity("Volo.Abp.Identity.IdentitySession", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Device") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("DeviceInfo") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("IpAddresses") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("LastAccessed") + .HasColumnType("datetime2"); + + b.Property("SessionId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("SignedIn") + .HasColumnType("datetime2"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("Device"); + + b.HasIndex("SessionId"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AbpSessions", (string)null); + }); + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => { b.Property("Id") diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20240125061143_Initial.Designer.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20240312033558_Initial.Designer.cs similarity index 97% rename from templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20240125061143_Initial.Designer.cs rename to templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20240312033558_Initial.Designer.cs index 54929eb8e9..fc604df03b 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20240125061143_Initial.Designer.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20240312033558_Initial.Designer.cs @@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore; namespace MyCompanyName.MyProjectName.Mvc.Migrations { [DbContext(typeof(MyProjectNameDbContext))] - [Migration("20240125061143_Initial")] + [Migration("20240312033558_Initial")] partial class Initial { /// @@ -647,6 +647,58 @@ namespace MyCompanyName.MyProjectName.Mvc.Migrations b.ToTable("AbpSecurityLogs", (string)null); }); + modelBuilder.Entity("Volo.Abp.Identity.IdentitySession", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Device") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("DeviceInfo") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("IpAddresses") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("LastAccessed") + .HasColumnType("datetime2"); + + b.Property("SessionId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("SignedIn") + .HasColumnType("datetime2"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("Device"); + + b.HasIndex("SessionId"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AbpSessions", (string)null); + }); + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => { b.Property("Id") diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20240125061143_Initial.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20240312033558_Initial.cs similarity index 96% rename from templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20240125061143_Initial.cs rename to templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20240312033558_Initial.cs index 44eddb6abb..88e57c1ebb 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20240125061143_Initial.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/20240312033558_Initial.cs @@ -255,6 +255,26 @@ namespace MyCompanyName.MyProjectName.Mvc.Migrations table.PrimaryKey("PK_AbpSecurityLogs", x => x.Id); }); + migrationBuilder.CreateTable( + name: "AbpSessions", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + SessionId = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + Device = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + DeviceInfo = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + UserId = table.Column(type: "uniqueidentifier", nullable: false), + ClientId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + IpAddresses = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + SignedIn = table.Column(type: "datetime2", nullable: false), + LastAccessed = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AbpSessions", x => x.Id); + }); + migrationBuilder.CreateTable( name: "AbpSettingDefinitions", columns: table => new @@ -896,6 +916,21 @@ namespace MyCompanyName.MyProjectName.Mvc.Migrations table: "AbpSecurityLogs", columns: new[] { "TenantId", "UserId" }); + migrationBuilder.CreateIndex( + name: "IX_AbpSessions_Device", + table: "AbpSessions", + column: "Device"); + + migrationBuilder.CreateIndex( + name: "IX_AbpSessions_SessionId", + table: "AbpSessions", + column: "SessionId"); + + migrationBuilder.CreateIndex( + name: "IX_AbpSessions_TenantId_UserId", + table: "AbpSessions", + columns: new[] { "TenantId", "UserId" }); + migrationBuilder.CreateIndex( name: "IX_AbpSettingDefinitions_Name", table: "AbpSettingDefinitions", @@ -1032,6 +1067,9 @@ namespace MyCompanyName.MyProjectName.Mvc.Migrations migrationBuilder.DropTable( name: "AbpSecurityLogs"); + migrationBuilder.DropTable( + name: "AbpSessions"); + migrationBuilder.DropTable( name: "AbpSettingDefinitions"); diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/MyProjectNameDbContextModelSnapshot.cs b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/MyProjectNameDbContextModelSnapshot.cs index 8041069541..17a23b24a7 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/MyProjectNameDbContextModelSnapshot.cs +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Migrations/MyProjectNameDbContextModelSnapshot.cs @@ -644,6 +644,58 @@ namespace MyCompanyName.MyProjectName.Mvc.Migrations b.ToTable("AbpSecurityLogs", (string)null); }); + modelBuilder.Entity("Volo.Abp.Identity.IdentitySession", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Device") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("DeviceInfo") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("IpAddresses") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("LastAccessed") + .HasColumnType("datetime2"); + + b.Property("SessionId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("SignedIn") + .HasColumnType("datetime2"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("Device"); + + b.HasIndex("SessionId"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AbpSessions", (string)null); + }); + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => { b.Property("Id") diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/EntityFrameworkCore/MyProjectNameDbContext.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/EntityFrameworkCore/MyProjectNameDbContext.cs index e1afd1a339..3e317d5cd8 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/EntityFrameworkCore/MyProjectNameDbContext.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/EntityFrameworkCore/MyProjectNameDbContext.cs @@ -46,7 +46,7 @@ public class MyProjectNameDbContext : public DbSet SecurityLogs { get; set; } public DbSet LinkUsers { get; set; } public DbSet UserDelegations { get; set; } - + public DbSet Sessions { get; set; } // Tenant Management public DbSet Tenants { get; set; } public DbSet TenantConnectionStrings { get; set; } diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20240125061344_Initial.Designer.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20240322114004_Initial.Designer.cs similarity index 94% rename from templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20240125061344_Initial.Designer.cs rename to templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20240322114004_Initial.Designer.cs index b6dd932e2f..bd99dc092f 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20240125061344_Initial.Designer.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20240322114004_Initial.Designer.cs @@ -12,8 +12,8 @@ using Volo.Abp.EntityFrameworkCore; namespace MyCompanyName.MyProjectName.Migrations { - [DbContext(typeof(AuthServerDbContext))] - [Migration("20240125061344_Initial")] + [DbContext(typeof(MyProjectNameDbContext))] + [Migration("20240322114004_Initial")] partial class Initial { /// @@ -290,6 +290,66 @@ namespace MyCompanyName.MyProjectName.Migrations b.ToTable("AbpEntityPropertyChanges", (string)null); }); + modelBuilder.Entity("Volo.Abp.BackgroundJobs.BackgroundJobRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsAbandoned") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("JobArgs") + .IsRequired() + .HasMaxLength(1048576) + .HasColumnType("nvarchar(max)"); + + b.Property("JobName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("LastTryTime") + .HasColumnType("datetime2"); + + b.Property("NextTryTime") + .HasColumnType("datetime2"); + + b.Property("Priority") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint") + .HasDefaultValue((byte)15); + + b.Property("TryCount") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasDefaultValue((short)0); + + b.HasKey("Id"); + + b.HasIndex("IsAbandoned", "NextTryTime"); + + b.ToTable("AbpBackgroundJobs", (string)null); + }); + modelBuilder.Entity("Volo.Abp.FeatureManagement.FeatureDefinitionRecord", b => { b.Property("Id") @@ -415,7 +475,6 @@ namespace MyCompanyName.MyProjectName.Migrations modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b => { b.Property("Id") - .ValueGeneratedOnAdd() .HasColumnType("uniqueidentifier"); b.Property("ConcurrencyStamp") @@ -464,7 +523,6 @@ namespace MyCompanyName.MyProjectName.Migrations modelBuilder.Entity("Volo.Abp.Identity.IdentityLinkUser", b => { b.Property("Id") - .ValueGeneratedOnAdd() .HasColumnType("uniqueidentifier"); b.Property("SourceTenantId") @@ -491,7 +549,6 @@ namespace MyCompanyName.MyProjectName.Migrations modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b => { b.Property("Id") - .ValueGeneratedOnAdd() .HasColumnType("uniqueidentifier"); b.Property("ConcurrencyStamp") @@ -573,7 +630,6 @@ namespace MyCompanyName.MyProjectName.Migrations modelBuilder.Entity("Volo.Abp.Identity.IdentitySecurityLog", b => { b.Property("Id") - .ValueGeneratedOnAdd() .HasColumnType("uniqueidentifier"); b.Property("Action") @@ -647,10 +703,60 @@ namespace MyCompanyName.MyProjectName.Migrations b.ToTable("AbpSecurityLogs", (string)null); }); + modelBuilder.Entity("Volo.Abp.Identity.IdentitySession", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Device") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("DeviceInfo") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("IpAddresses") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("LastAccessed") + .HasColumnType("datetime2"); + + b.Property("SessionId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("SignedIn") + .HasColumnType("datetime2"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("Device"); + + b.HasIndex("SessionId"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AbpSessions", (string)null); + }); + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => { b.Property("Id") - .ValueGeneratedOnAdd() .HasColumnType("uniqueidentifier"); b.Property("AccessFailedCount") @@ -845,7 +951,6 @@ namespace MyCompanyName.MyProjectName.Migrations modelBuilder.Entity("Volo.Abp.Identity.IdentityUserDelegation", b => { b.Property("Id") - .ValueGeneratedOnAdd() .HasColumnType("uniqueidentifier"); b.Property("EndTime") @@ -972,7 +1077,6 @@ namespace MyCompanyName.MyProjectName.Migrations modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => { b.Property("Id") - .ValueGeneratedOnAdd() .HasColumnType("uniqueidentifier"); b.Property("Code") @@ -1634,7 +1738,6 @@ namespace MyCompanyName.MyProjectName.Migrations modelBuilder.Entity("Volo.Abp.TenantManagement.Tenant", b => { b.Property("Id") - .ValueGeneratedOnAdd() .HasColumnType("uniqueidentifier"); b.Property("ConcurrencyStamp") diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20240125061501_Initial.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20240322114004_Initial.cs similarity index 94% rename from templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20240125061501_Initial.cs rename to templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20240322114004_Initial.cs index b0cb9b0e6f..3c914f3225 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Server/Migrations/20240125061501_Initial.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20240322114004_Initial.cs @@ -45,6 +45,27 @@ namespace MyCompanyName.MyProjectName.Migrations table.PrimaryKey("PK_AbpAuditLogs", x => x.Id); }); + migrationBuilder.CreateTable( + name: "AbpBackgroundJobs", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + JobName = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + JobArgs = table.Column(type: "nvarchar(max)", maxLength: 1048576, nullable: false), + TryCount = table.Column(type: "smallint", nullable: false, defaultValue: (short)0), + CreationTime = table.Column(type: "datetime2", nullable: false), + NextTryTime = table.Column(type: "datetime2", nullable: false), + LastTryTime = table.Column(type: "datetime2", nullable: true), + IsAbandoned = table.Column(type: "bit", nullable: false, defaultValue: false), + Priority = table.Column(type: "tinyint", nullable: false, defaultValue: (byte)15), + ExtraProperties = table.Column(type: "nvarchar(max)", nullable: false), + ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AbpBackgroundJobs", x => x.Id); + }); + migrationBuilder.CreateTable( name: "AbpClaimTypes", columns: table => new @@ -255,6 +276,26 @@ namespace MyCompanyName.MyProjectName.Migrations table.PrimaryKey("PK_AbpSecurityLogs", x => x.Id); }); + migrationBuilder.CreateTable( + name: "AbpSessions", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + SessionId = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + Device = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + DeviceInfo = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + UserId = table.Column(type: "uniqueidentifier", nullable: false), + ClientId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + IpAddresses = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + SignedIn = table.Column(type: "datetime2", nullable: false), + LastAccessed = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AbpSessions", x => x.Id); + }); + migrationBuilder.CreateTable( name: "AbpSettingDefinitions", columns: table => new @@ -781,6 +822,11 @@ namespace MyCompanyName.MyProjectName.Migrations table: "AbpAuditLogs", columns: new[] { "TenantId", "UserId", "ExecutionTime" }); + migrationBuilder.CreateIndex( + name: "IX_AbpBackgroundJobs_IsAbandoned_NextTryTime", + table: "AbpBackgroundJobs", + columns: new[] { "IsAbandoned", "NextTryTime" }); + migrationBuilder.CreateIndex( name: "IX_AbpEntityChanges_AuditLogId", table: "AbpEntityChanges", @@ -896,6 +942,21 @@ namespace MyCompanyName.MyProjectName.Migrations table: "AbpSecurityLogs", columns: new[] { "TenantId", "UserId" }); + migrationBuilder.CreateIndex( + name: "IX_AbpSessions_Device", + table: "AbpSessions", + column: "Device"); + + migrationBuilder.CreateIndex( + name: "IX_AbpSessions_SessionId", + table: "AbpSessions", + column: "SessionId"); + + migrationBuilder.CreateIndex( + name: "IX_AbpSessions_TenantId_UserId", + table: "AbpSessions", + columns: new[] { "TenantId", "UserId" }); + migrationBuilder.CreateIndex( name: "IX_AbpSettingDefinitions_Name", table: "AbpSettingDefinitions", @@ -996,6 +1057,9 @@ namespace MyCompanyName.MyProjectName.Migrations migrationBuilder.DropTable( name: "AbpAuditLogActions"); + migrationBuilder.DropTable( + name: "AbpBackgroundJobs"); + migrationBuilder.DropTable( name: "AbpClaimTypes"); @@ -1032,6 +1096,9 @@ namespace MyCompanyName.MyProjectName.Migrations migrationBuilder.DropTable( name: "AbpSecurityLogs"); + migrationBuilder.DropTable( + name: "AbpSessions"); + migrationBuilder.DropTable( name: "AbpSettingDefinitions"); diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/MyProjectNameDbContextModelSnapshot.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/MyProjectNameDbContextModelSnapshot.cs index 877bff36e8..6aca735728 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/MyProjectNameDbContextModelSnapshot.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/MyProjectNameDbContextModelSnapshot.cs @@ -700,6 +700,57 @@ namespace MyCompanyName.MyProjectName.Migrations b.ToTable("AbpSecurityLogs", (string)null); }); + modelBuilder.Entity("Volo.Abp.Identity.IdentitySession", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Device") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("DeviceInfo") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("IpAddresses") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("LastAccessed") + .HasColumnType("datetime2"); + + b.Property("SessionId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("SignedIn") + .HasColumnType("datetime2"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("Device"); + + b.HasIndex("SessionId"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AbpSessions", (string)null); + }); + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => { b.Property("Id") diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20240125061248_Initial.Designer.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20240321011622_Initial.Designer.cs similarity index 97% rename from templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20240125061248_Initial.Designer.cs rename to templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20240321011622_Initial.Designer.cs index e211d7e755..6e7456f3ba 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore/Migrations/20240125061248_Initial.Designer.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20240321011622_Initial.Designer.cs @@ -12,8 +12,8 @@ using Volo.Abp.EntityFrameworkCore; namespace MyCompanyName.MyProjectName.Migrations { - [DbContext(typeof(MyProjectNameDbContext))] - [Migration("20240125061248_Initial")] + [DbContext(typeof(AuthServerDbContext))] + [Migration("20240321011622_Initial")] partial class Initial { /// @@ -290,66 +290,6 @@ namespace MyCompanyName.MyProjectName.Migrations b.ToTable("AbpEntityPropertyChanges", (string)null); }); - modelBuilder.Entity("Volo.Abp.BackgroundJobs.BackgroundJobRecord", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .IsRequired() - .HasMaxLength(40) - .HasColumnType("nvarchar(40)") - .HasColumnName("ConcurrencyStamp"); - - b.Property("CreationTime") - .HasColumnType("datetime2") - .HasColumnName("CreationTime"); - - b.Property("ExtraProperties") - .IsRequired() - .HasColumnType("nvarchar(max)") - .HasColumnName("ExtraProperties"); - - b.Property("IsAbandoned") - .ValueGeneratedOnAdd() - .HasColumnType("bit") - .HasDefaultValue(false); - - b.Property("JobArgs") - .IsRequired() - .HasMaxLength(1048576) - .HasColumnType("nvarchar(max)"); - - b.Property("JobName") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("LastTryTime") - .HasColumnType("datetime2"); - - b.Property("NextTryTime") - .HasColumnType("datetime2"); - - b.Property("Priority") - .ValueGeneratedOnAdd() - .HasColumnType("tinyint") - .HasDefaultValue((byte)15); - - b.Property("TryCount") - .ValueGeneratedOnAdd() - .HasColumnType("smallint") - .HasDefaultValue((short)0); - - b.HasKey("Id"); - - b.HasIndex("IsAbandoned", "NextTryTime"); - - b.ToTable("AbpBackgroundJobs", (string)null); - }); - modelBuilder.Entity("Volo.Abp.FeatureManagement.FeatureDefinitionRecord", b => { b.Property("Id") @@ -475,6 +415,7 @@ namespace MyCompanyName.MyProjectName.Migrations modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b => { b.Property("Id") + .ValueGeneratedOnAdd() .HasColumnType("uniqueidentifier"); b.Property("ConcurrencyStamp") @@ -523,6 +464,7 @@ namespace MyCompanyName.MyProjectName.Migrations modelBuilder.Entity("Volo.Abp.Identity.IdentityLinkUser", b => { b.Property("Id") + .ValueGeneratedOnAdd() .HasColumnType("uniqueidentifier"); b.Property("SourceTenantId") @@ -549,6 +491,7 @@ namespace MyCompanyName.MyProjectName.Migrations modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b => { b.Property("Id") + .ValueGeneratedOnAdd() .HasColumnType("uniqueidentifier"); b.Property("ConcurrencyStamp") @@ -630,6 +573,7 @@ namespace MyCompanyName.MyProjectName.Migrations modelBuilder.Entity("Volo.Abp.Identity.IdentitySecurityLog", b => { b.Property("Id") + .ValueGeneratedOnAdd() .HasColumnType("uniqueidentifier"); b.Property("Action") @@ -703,9 +647,62 @@ namespace MyCompanyName.MyProjectName.Migrations b.ToTable("AbpSecurityLogs", (string)null); }); + modelBuilder.Entity("Volo.Abp.Identity.IdentitySession", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Device") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("DeviceInfo") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("IpAddresses") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("LastAccessed") + .HasColumnType("datetime2"); + + b.Property("SessionId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("SignedIn") + .HasColumnType("datetime2"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("Device"); + + b.HasIndex("SessionId"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AbpSessions", (string)null); + }); + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => { b.Property("Id") + .ValueGeneratedOnAdd() .HasColumnType("uniqueidentifier"); b.Property("AccessFailedCount") @@ -900,6 +897,7 @@ namespace MyCompanyName.MyProjectName.Migrations modelBuilder.Entity("Volo.Abp.Identity.IdentityUserDelegation", b => { b.Property("Id") + .ValueGeneratedOnAdd() .HasColumnType("uniqueidentifier"); b.Property("EndTime") @@ -1026,6 +1024,7 @@ namespace MyCompanyName.MyProjectName.Migrations modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => { b.Property("Id") + .ValueGeneratedOnAdd() .HasColumnType("uniqueidentifier"); b.Property("Code") @@ -1687,6 +1686,7 @@ namespace MyCompanyName.MyProjectName.Migrations modelBuilder.Entity("Volo.Abp.TenantManagement.Tenant", b => { b.Property("Id") + .ValueGeneratedOnAdd() .HasColumnType("uniqueidentifier"); b.Property("ConcurrencyStamp") diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20240125061344_Initial.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20240321011622_Initial.cs similarity index 96% rename from templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20240125061344_Initial.cs rename to templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20240321011622_Initial.cs index b0cb9b0e6f..a3dbf4a768 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20240125061344_Initial.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/20240321011622_Initial.cs @@ -255,6 +255,26 @@ namespace MyCompanyName.MyProjectName.Migrations table.PrimaryKey("PK_AbpSecurityLogs", x => x.Id); }); + migrationBuilder.CreateTable( + name: "AbpSessions", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + SessionId = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + Device = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + DeviceInfo = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + UserId = table.Column(type: "uniqueidentifier", nullable: false), + ClientId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + IpAddresses = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + SignedIn = table.Column(type: "datetime2", nullable: false), + LastAccessed = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AbpSessions", x => x.Id); + }); + migrationBuilder.CreateTable( name: "AbpSettingDefinitions", columns: table => new @@ -896,6 +916,21 @@ namespace MyCompanyName.MyProjectName.Migrations table: "AbpSecurityLogs", columns: new[] { "TenantId", "UserId" }); + migrationBuilder.CreateIndex( + name: "IX_AbpSessions_Device", + table: "AbpSessions", + column: "Device"); + + migrationBuilder.CreateIndex( + name: "IX_AbpSessions_SessionId", + table: "AbpSessions", + column: "SessionId"); + + migrationBuilder.CreateIndex( + name: "IX_AbpSessions_TenantId_UserId", + table: "AbpSessions", + columns: new[] { "TenantId", "UserId" }); + migrationBuilder.CreateIndex( name: "IX_AbpSettingDefinitions_Name", table: "AbpSettingDefinitions", @@ -1032,6 +1067,9 @@ namespace MyCompanyName.MyProjectName.Migrations migrationBuilder.DropTable( name: "AbpSecurityLogs"); + migrationBuilder.DropTable( + name: "AbpSessions"); + migrationBuilder.DropTable( name: "AbpSettingDefinitions"); diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/AuthServerDbContextModelSnapshot.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/AuthServerDbContextModelSnapshot.cs index c3fb7f9ff0..4da168ec59 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/AuthServerDbContextModelSnapshot.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.AuthServer/Migrations/AuthServerDbContextModelSnapshot.cs @@ -644,6 +644,58 @@ namespace MyCompanyName.MyProjectName.Migrations b.ToTable("AbpSecurityLogs", (string)null); }); + modelBuilder.Entity("Volo.Abp.Identity.IdentitySession", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Device") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("DeviceInfo") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("IpAddresses") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("LastAccessed") + .HasColumnType("datetime2"); + + b.Property("SessionId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("SignedIn") + .HasColumnType("datetime2"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("Device"); + + b.HasIndex("SessionId"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AbpSessions", (string)null); + }); + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => { b.Property("Id") diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/20240125061321_Initial.Designer.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/20240312033728_Initial.Designer.cs similarity index 96% rename from templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/20240125061321_Initial.Designer.cs rename to templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/20240312033728_Initial.Designer.cs index 3c17670e22..cc7dab7c4b 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/20240125061321_Initial.Designer.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/20240312033728_Initial.Designer.cs @@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore; namespace MyCompanyName.MyProjectName.Blazor.Server.Host.Migrations { [DbContext(typeof(UnifiedDbContext))] - [Migration("20240125061321_Initial")] + [Migration("20240312033728_Initial")] partial class Initial { /// @@ -647,6 +647,58 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Host.Migrations b.ToTable("AbpSecurityLogs", (string)null); }); + modelBuilder.Entity("Volo.Abp.Identity.IdentitySession", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Device") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("DeviceInfo") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("IpAddresses") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("LastAccessed") + .HasColumnType("datetime2"); + + b.Property("SessionId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("SignedIn") + .HasColumnType("datetime2"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("Device"); + + b.HasIndex("SessionId"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AbpSessions", (string)null); + }); + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => { b.Property("Id") diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/20240125061321_Initial.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/20240312033728_Initial.cs similarity index 96% rename from templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/20240125061321_Initial.cs rename to templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/20240312033728_Initial.cs index 1a8774f577..b79afe38fe 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/20240125061321_Initial.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/20240312033728_Initial.cs @@ -255,6 +255,26 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Host.Migrations table.PrimaryKey("PK_AbpSecurityLogs", x => x.Id); }); + migrationBuilder.CreateTable( + name: "AbpSessions", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + SessionId = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + Device = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + DeviceInfo = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + UserId = table.Column(type: "uniqueidentifier", nullable: false), + ClientId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + IpAddresses = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + SignedIn = table.Column(type: "datetime2", nullable: false), + LastAccessed = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AbpSessions", x => x.Id); + }); + migrationBuilder.CreateTable( name: "AbpSettingDefinitions", columns: table => new @@ -760,6 +780,21 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Host.Migrations table: "AbpSecurityLogs", columns: new[] { "TenantId", "UserId" }); + migrationBuilder.CreateIndex( + name: "IX_AbpSessions_Device", + table: "AbpSessions", + column: "Device"); + + migrationBuilder.CreateIndex( + name: "IX_AbpSessions_SessionId", + table: "AbpSessions", + column: "SessionId"); + + migrationBuilder.CreateIndex( + name: "IX_AbpSessions_TenantId_UserId", + table: "AbpSessions", + columns: new[] { "TenantId", "UserId" }); + migrationBuilder.CreateIndex( name: "IX_AbpSettingDefinitions_Name", table: "AbpSettingDefinitions", @@ -866,6 +901,9 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Host.Migrations migrationBuilder.DropTable( name: "AbpSecurityLogs"); + migrationBuilder.DropTable( + name: "AbpSessions"); + migrationBuilder.DropTable( name: "AbpSettingDefinitions"); diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/UnifiedDbContextModelSnapshot.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/UnifiedDbContextModelSnapshot.cs index 4acfb0c562..8c80cc940f 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/UnifiedDbContextModelSnapshot.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Blazor.Server.Host/Migrations/UnifiedDbContextModelSnapshot.cs @@ -644,6 +644,58 @@ namespace MyCompanyName.MyProjectName.Blazor.Server.Host.Migrations b.ToTable("AbpSecurityLogs", (string)null); }); + modelBuilder.Entity("Volo.Abp.Identity.IdentitySession", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Device") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("DeviceInfo") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("IpAddresses") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("LastAccessed") + .HasColumnType("datetime2"); + + b.Property("SessionId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("SignedIn") + .HasColumnType("datetime2"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("Device"); + + b.HasIndex("SessionId"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AbpSessions", (string)null); + }); + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => { b.Property("Id") diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Migrations/20240125061400_Initial.Designer.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Migrations/20240312033807_Initial.Designer.cs similarity index 96% rename from templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Migrations/20240125061400_Initial.Designer.cs rename to templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Migrations/20240312033807_Initial.Designer.cs index c58552ea60..3407609e8f 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Migrations/20240125061400_Initial.Designer.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Migrations/20240312033807_Initial.Designer.cs @@ -12,7 +12,7 @@ using Volo.Abp.EntityFrameworkCore; namespace MyCompanyName.MyProjectName.Migrations { [DbContext(typeof(MyProjectNameHttpApiHostMigrationsDbContext))] - [Migration("20240125061400_Initial")] + [Migration("20240312033807_Initial")] partial class Initial { /// diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Migrations/20240125061400_Initial.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Migrations/20240312033807_Initial.cs similarity index 100% rename from templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Migrations/20240125061400_Initial.cs rename to templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/Migrations/20240312033807_Initial.cs diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20240125061424_Initial.Designer.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20240312033830_Initial.Designer.cs similarity index 96% rename from templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20240125061424_Initial.Designer.cs rename to templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20240312033830_Initial.Designer.cs index 04cad1c308..618206a870 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20240125061424_Initial.Designer.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20240312033830_Initial.Designer.cs @@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore; namespace MyCompanyName.MyProjectName.Migrations { [DbContext(typeof(UnifiedDbContext))] - [Migration("20240125061424_Initial")] + [Migration("20240312033830_Initial")] partial class Initial { /// @@ -647,6 +647,58 @@ namespace MyCompanyName.MyProjectName.Migrations b.ToTable("AbpSecurityLogs", (string)null); }); + modelBuilder.Entity("Volo.Abp.Identity.IdentitySession", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Device") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("DeviceInfo") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("IpAddresses") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("LastAccessed") + .HasColumnType("datetime2"); + + b.Property("SessionId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("SignedIn") + .HasColumnType("datetime2"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("Device"); + + b.HasIndex("SessionId"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AbpSessions", (string)null); + }); + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => { b.Property("Id") diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20240125061424_Initial.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20240312033830_Initial.cs similarity index 96% rename from templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20240125061424_Initial.cs rename to templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20240312033830_Initial.cs index 469e6eac08..105890a571 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20240125061424_Initial.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20240312033830_Initial.cs @@ -255,6 +255,26 @@ namespace MyCompanyName.MyProjectName.Migrations table.PrimaryKey("PK_AbpSecurityLogs", x => x.Id); }); + migrationBuilder.CreateTable( + name: "AbpSessions", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + SessionId = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + Device = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + DeviceInfo = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + UserId = table.Column(type: "uniqueidentifier", nullable: false), + ClientId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + IpAddresses = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + SignedIn = table.Column(type: "datetime2", nullable: false), + LastAccessed = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AbpSessions", x => x.Id); + }); + migrationBuilder.CreateTable( name: "AbpSettingDefinitions", columns: table => new @@ -760,6 +780,21 @@ namespace MyCompanyName.MyProjectName.Migrations table: "AbpSecurityLogs", columns: new[] { "TenantId", "UserId" }); + migrationBuilder.CreateIndex( + name: "IX_AbpSessions_Device", + table: "AbpSessions", + column: "Device"); + + migrationBuilder.CreateIndex( + name: "IX_AbpSessions_SessionId", + table: "AbpSessions", + column: "SessionId"); + + migrationBuilder.CreateIndex( + name: "IX_AbpSessions_TenantId_UserId", + table: "AbpSessions", + columns: new[] { "TenantId", "UserId" }); + migrationBuilder.CreateIndex( name: "IX_AbpSettingDefinitions_Name", table: "AbpSettingDefinitions", @@ -866,6 +901,9 @@ namespace MyCompanyName.MyProjectName.Migrations migrationBuilder.DropTable( name: "AbpSecurityLogs"); + migrationBuilder.DropTable( + name: "AbpSessions"); + migrationBuilder.DropTable( name: "AbpSettingDefinitions"); diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs index b6fd7b9e97..59eae27537 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs @@ -644,6 +644,58 @@ namespace MyCompanyName.MyProjectName.Migrations b.ToTable("AbpSecurityLogs", (string)null); }); + modelBuilder.Entity("Volo.Abp.Identity.IdentitySession", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Device") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("DeviceInfo") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("IpAddresses") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("LastAccessed") + .HasColumnType("datetime2"); + + b.Property("SessionId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("SignedIn") + .HasColumnType("datetime2"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("Device"); + + b.HasIndex("SessionId"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AbpSessions", (string)null); + }); + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => { b.Property("Id")