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