diff --git a/Oqtane.Client/Services/ModuleDefinitionService.cs b/Oqtane.Client/Services/ModuleDefinitionService.cs index 9be0c222..a2952e4c 100644 --- a/Oqtane.Client/Services/ModuleDefinitionService.cs +++ b/Oqtane.Client/Services/ModuleDefinitionService.cs @@ -7,6 +7,7 @@ using Microsoft.AspNetCore.Components; using System; using System.Reflection; using Oqtane.Shared; +using Oqtane.Providers; namespace Oqtane.Services { @@ -15,12 +16,14 @@ namespace Oqtane.Services private readonly HttpClient _http; private readonly SiteState _siteState; private readonly NavigationManager _navigationManager; + private readonly IServiceProvider _serviceProvider; - public ModuleDefinitionService(HttpClient http, SiteState siteState, NavigationManager navigationManager) + public ModuleDefinitionService(HttpClient http, SiteState siteState, NavigationManager navigationManager, IServiceProvider serviceProvider) { _http = http; _siteState = siteState; _navigationManager = navigationManager; + _serviceProvider = serviceProvider; } private string apiurl @@ -56,34 +59,39 @@ namespace Oqtane.Services public async Task LoadModuleDefinitionsAsync(int SiteId) { - // get list of modules from the server - List moduledefinitions = await GetModuleDefinitionsAsync(SiteId); - - // get list of loaded assemblies on the client ( in the client-side hosting module the browser client has its own app domain ) - Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); - - foreach (ModuleDefinition moduledefinition in moduledefinitions) + // download assemblies to browser when running client-side Blazor + var authstateprovider = (IdentityAuthenticationStateProvider)_serviceProvider.GetService(typeof(IdentityAuthenticationStateProvider)); + if (authstateprovider != null) { - // if a module has dependencies, check if they are loaded - if (moduledefinition.Dependencies != "") + // get list of modules from the server + List moduledefinitions = await GetModuleDefinitionsAsync(SiteId); + + // get list of loaded assemblies on the client ( in the client-side hosting module the browser client has its own app domain ) + Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); + + foreach (ModuleDefinition moduledefinition in moduledefinitions) { - foreach (string dependency in moduledefinition.Dependencies.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries)) + // if a module has dependencies, check if they are loaded + if (moduledefinition.Dependencies != "") { - string assemblyname = dependency.Replace(".dll", ""); - if (assemblies.Where(item => item.FullName.StartsWith(assemblyname + ",")).FirstOrDefault() == null) + foreach (string dependency in moduledefinition.Dependencies.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries)) { - // download assembly from server and load - var bytes = await _http.GetByteArrayAsync(apiurl + "/load/" + assemblyname + ".dll"); - Assembly.Load(bytes); + string assemblyname = dependency.Replace(".dll", ""); + if (assemblies.Where(item => item.FullName.StartsWith(assemblyname + ",")).FirstOrDefault() == null) + { + // download assembly from server and load + var bytes = await _http.GetByteArrayAsync(apiurl + "/load/" + assemblyname + ".dll"); + Assembly.Load(bytes); + } } } - } - // check if the module assembly is loaded - if (assemblies.Where(item => item.FullName.StartsWith(moduledefinition.AssemblyName + ",")).FirstOrDefault() == null) - { - // download assembly from server and load - var bytes = await _http.GetByteArrayAsync(apiurl + "/load/" + moduledefinition.AssemblyName + ".dll"); - Assembly.Load(bytes); + // check if the module assembly is loaded + if (assemblies.Where(item => item.FullName.StartsWith(moduledefinition.AssemblyName + ",")).FirstOrDefault() == null) + { + // download assembly from server and load + var bytes = await _http.GetByteArrayAsync(apiurl + "/load/" + moduledefinition.AssemblyName + ".dll"); + Assembly.Load(bytes); + } } } } diff --git a/Oqtane.Client/Themes/Controls/Login.razor b/Oqtane.Client/Themes/Controls/Login.razor index 7abcebd0..522bd6e3 100644 --- a/Oqtane.Client/Themes/Controls/Login.razor +++ b/Oqtane.Client/Themes/Controls/Login.razor @@ -46,7 +46,7 @@ { // client-side Blazor authstateprovider.NotifyAuthenticationChanged(); - NavigationManager.NavigateTo(NavigateUrl(PageState.Page.Path, "logout")); + NavigationManager.NavigateTo(NavigateUrl(PageState.Page.Path)); } } } diff --git a/Oqtane.Client/UI/SiteRouter.razor b/Oqtane.Client/UI/SiteRouter.razor index b1344e32..a21fbe39 100644 --- a/Oqtane.Client/UI/SiteRouter.razor +++ b/Oqtane.Client/UI/SiteRouter.razor @@ -75,8 +75,9 @@ int moduleid = -1; string action = ""; bool editmode = false; + int userid = -1; Reload reload = Reload.None; - DateTime lastsyncdate = DateTime.Now; + DateTime lastsyncdate = DateTime.UtcNow; // get Url path and querystring ( and remove anchors ) string path = new Uri(_absoluteUri).PathAndQuery.Substring(1); @@ -97,7 +98,10 @@ { editmode = PageState.EditMode; lastsyncdate = PageState.LastSyncDate; - user = PageState.User; + if (PageState.User != null) + { + userid = PageState.User.UserId; + } } alias = await AliasService.GetAliasAsync(_absoluteUri, lastsyncdate); @@ -114,6 +118,17 @@ } if (site != null) { + // get user + var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync(); + if (authState.User.Identity.IsAuthenticated) + { + user = await UserService.GetUserAsync(authState.User.Identity.Name, site.SiteId); + if (user != null) + { + userid = user.UserId; + } + } + // process sync events if (alias.SyncEvents.Any()) { @@ -125,7 +140,7 @@ { reload = Reload.Site; } - if (user != null && alias.SyncEvents.Exists(item => item.EntityName == "User" && item.EntityId == user.UserId)) + if (alias.SyncEvents.Exists(item => item.EntityName == "User" && item.EntityId == userid)) { reload = Reload.Site; } @@ -133,15 +148,7 @@ if (PageState == null || reload >= Reload.Site) { -#if WASM - ModuleDefinitionService.LoadModuleDefinitionsAsync(site.SiteId); // download assemblies to browser when running client-side -#endif - - var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync(); - if (authState.User.Identity.IsAuthenticated) - { - user = await UserService.GetUserAsync(authState.User.Identity.Name, site.SiteId); - } + await ModuleDefinitionService.LoadModuleDefinitionsAsync(site.SiteId); pages = await PageService.GetPagesAsync(site.SiteId); } else @@ -205,20 +212,6 @@ } } - user = null; - if (PageState == null || reload >= Reload.Page) - { - var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync(); - if (authState.User.Identity.IsAuthenticated) - { - user = await UserService.GetUserAsync(authState.User.Identity.Name, site.SiteId); - } - } - else - { - user = PageState.User; - } - if (page != null) { if (PageState == null) diff --git a/Oqtane.Server/Controllers/AliasController.cs b/Oqtane.Server/Controllers/AliasController.cs index e8242bee..20eeba79 100644 --- a/Oqtane.Server/Controllers/AliasController.cs +++ b/Oqtane.Server/Controllers/AliasController.cs @@ -62,7 +62,7 @@ namespace Oqtane.Controllers } // get sync events - alias.SyncDate = DateTime.Now; + alias.SyncDate = DateTime.UtcNow; alias.SyncEvents = _syncManager.GetSyncEvents(DateTime.ParseExact(lastsyncdate, "yyyyMMddHHmmssfff", CultureInfo.InvariantCulture)); return alias; diff --git a/Oqtane.Server/Controllers/UserController.cs b/Oqtane.Server/Controllers/UserController.cs index d75f2921..1a8cdef2 100644 --- a/Oqtane.Server/Controllers/UserController.cs +++ b/Oqtane.Server/Controllers/UserController.cs @@ -243,7 +243,7 @@ namespace Oqtane.Controllers user.LastLoginOn = DateTime.Now; user.LastIPAddress = HttpContext.Connection.RemoteIpAddress.ToString(); _users.UpdateUser(user); - _syncManager.AddSyncEvent("User", User.UserId); + _syncManager.AddSyncEvent("User", user.UserId); _logger.Log(LogLevel.Information, this, LogFunction.Security, "User Login Successful {Username}", User.Username); if (SetCookie) { diff --git a/Oqtane.Server/Infrastructure/SyncManager.cs b/Oqtane.Server/Infrastructure/SyncManager.cs index 5ae9f5cc..b9495e22 100644 --- a/Oqtane.Server/Infrastructure/SyncManager.cs +++ b/Oqtane.Server/Infrastructure/SyncManager.cs @@ -36,9 +36,9 @@ namespace Oqtane.Infrastructure public void AddSyncEvent(string EntityName, int EntityId) { - SyncEvents.Add(new SyncEvent { TenantId = TenantId, EntityName = EntityName, EntityId = EntityId, ModifiedOn = DateTime.Now }); + SyncEvents.Add(new SyncEvent { TenantId = TenantId, EntityName = EntityName, EntityId = EntityId, ModifiedOn = DateTime.UtcNow }); // trim sync events - SyncEvents.RemoveAll(item => item.ModifiedOn < DateTime.Now.AddHours(-1)); + SyncEvents.RemoveAll(item => item.ModifiedOn < DateTime.UtcNow.AddHours(-1)); } } } diff --git a/Oqtane.Server/Startup.cs b/Oqtane.Server/Startup.cs index 08a2a24b..55e2391a 100644 --- a/Oqtane.Server/Startup.cs +++ b/Oqtane.Server/Startup.cs @@ -313,6 +313,7 @@ namespace Oqtane.Server // register singleton scoped core services services.AddSingleton(Configuration); services.AddSingleton(); + services.AddSingleton(); // register transient scoped core services services.AddTransient();