Are You Sure You Want To Delete This Page?
@@ -537,7 +538,7 @@ } page.Permissions = UserSecurity.SetPermissionStrings(permissions); await PageService.UpdatePageAsync(page); - NavigationManager.NavigateTo(NavigateUrl(PageState.Page.Path, "reload")); + NavigationManager.NavigateTo(NavigateUrl(PageState.Page.Path, true)); } } diff --git a/Oqtane.Client/Themes/Controls/Theme/LoginBase.cs b/Oqtane.Client/Themes/Controls/Theme/LoginBase.cs index 972f005c..cc454412 100644 --- a/Oqtane.Client/Themes/Controls/Theme/LoginBase.cs +++ b/Oqtane.Client/Themes/Controls/Theme/LoginBase.cs @@ -47,7 +47,7 @@ namespace Oqtane.Themes.Controls // client-side Blazor var authstateprovider = (IdentityAuthenticationStateProvider)ServiceProvider.GetService(typeof(IdentityAuthenticationStateProvider)); authstateprovider.NotifyAuthenticationChanged(); - NavigationManager.NavigateTo(NavigateUrl(!authorizedtoviewpage ? PageState.Alias.Path : PageState.Page.Path, "reload")); + NavigationManager.NavigateTo(NavigateUrl(!authorizedtoviewpage ? PageState.Alias.Path : PageState.Page.Path, true)); } } } diff --git a/Oqtane.Client/Themes/ThemeBase.cs b/Oqtane.Client/Themes/ThemeBase.cs index a2ca3c86..158321f9 100644 --- a/Oqtane.Client/Themes/ThemeBase.cs +++ b/Oqtane.Client/Themes/ThemeBase.cs @@ -64,6 +64,16 @@ namespace Oqtane.Themes return NavigateUrl(path, ""); } + public string NavigateUrl(bool refresh) + { + return NavigateUrl(PageState.Page.Path, refresh); + } + + public string NavigateUrl(string path, bool refresh) + { + return Utilities.NavigateUrl(PageState.Alias.Path, path, refresh ? "refresh" : ""); + } + public string NavigateUrl(string path, string parameters) { return Utilities.NavigateUrl(PageState.Alias.Path, path, parameters); diff --git a/Oqtane.Client/UI/Reload.cs b/Oqtane.Client/UI/Refresh.cs similarity index 62% rename from Oqtane.Client/UI/Reload.cs rename to Oqtane.Client/UI/Refresh.cs index 6fb632c6..0c0d7871 100644 --- a/Oqtane.Client/UI/Reload.cs +++ b/Oqtane.Client/UI/Refresh.cs @@ -1,6 +1,6 @@ -namespace Oqtane.UI +namespace Oqtane.UI { - public enum Reload + public enum Refresh { None, Page, diff --git a/Oqtane.Client/UI/SiteRouter.razor b/Oqtane.Client/UI/SiteRouter.razor index ed5548f4..cbe7783a 100644 --- a/Oqtane.Client/UI/SiteRouter.razor +++ b/Oqtane.Client/UI/SiteRouter.razor @@ -77,7 +77,7 @@ var action = Constants.DefaultAction; var urlparameters = string.Empty; var editmode = false; - var reload = Reload.None; + var refresh = UI.Refresh.None; var lastsyncdate = DateTime.UtcNow.AddHours(-1); var runtime = GetRuntime(); @@ -89,10 +89,19 @@ // parse querystring var querystring = ParseQueryString(uri.Query); - // the reload parameter is used to reload the PageState - if (querystring.ContainsKey("reload")) + // the refresh parameter is used to refresh the PageState + if (querystring.ContainsKey("refresh")) { - reload = Reload.Site; + refresh = UI.Refresh.Site; + } + else + { + // reload the client application if the user navigated to a site with a different alias or there is a forced reload + if ((!path.StartsWith(SiteState.Alias.Path) && SiteState.Alias.Path != "") || querystring.ContainsKey("reload")) + { + NavigationManager.NavigateTo(_absoluteUri.Replace("?reload", ""), true); + return; + } } if (PageState != null) @@ -104,23 +113,24 @@ // process any sync events var sync = await SyncService.GetSyncAsync(lastsyncdate); lastsyncdate = sync.SyncDate; - if (reload != Reload.Site && sync.SyncEvents.Any()) + if (refresh != UI.Refresh.Site && sync.SyncEvents.Any()) { // if running on WebAssembly reload the client application if the server application was restarted if (runtime == Shared.Runtime.WebAssembly && PageState != null && sync.SyncEvents.Exists(item => item.TenantId == -1)) { - NavigationManager.NavigateTo(_absoluteUri + (!_absoluteUri.Contains("?") ? "?" : "&") + "reload", true); + NavigationManager.NavigateTo(_absoluteUri, true); + return; } if (sync.SyncEvents.Exists(item => item.EntityName == EntityNames.Site && item.EntityId == SiteState.Alias.SiteId)) { - reload = Reload.Site; + refresh = UI.Refresh.Site; } } - if (reload == Reload.Site || PageState == null || PageState.Alias.SiteId != SiteState.Alias.SiteId) + if (refresh == UI.Refresh.Site || PageState == null || PageState.Alias.SiteId != SiteState.Alias.SiteId) { site = await SiteService.GetSiteAsync(SiteState.Alias.SiteId); - reload = Reload.Site; + refresh = UI.Refresh.Site; } else { @@ -129,7 +139,7 @@ if (site != null) { - if (PageState == null || reload == Reload.Site) + if (PageState == null || refresh == UI.Refresh.Site) { // get user var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync(); @@ -144,15 +154,15 @@ } // process any sync events for user - if (reload != Reload.Site && user != null && sync.SyncEvents.Any()) + if (refresh != UI.Refresh.Site && user != null && sync.SyncEvents.Any()) { if (sync.SyncEvents.Exists(item => item.EntityName == EntityNames.User && item.EntityId == user.UserId)) { - reload = Reload.Site; + refresh = UI.Refresh.Site; } } - if (PageState == null || reload == Reload.Site) + if (PageState == null || refresh == UI.Refresh.Site) { pages = await PageService.GetPagesAsync(site.SiteId); } @@ -169,7 +179,7 @@ path += "/"; } - if (SiteState.Alias.Path != "") + if (SiteState.Alias.Path != "" && path.StartsWith(SiteState.Alias.Path)) { path = path.Substring(SiteState.Alias.Path.Length + 1); } @@ -229,7 +239,7 @@ // remove trailing slash so it can be used as a key for Pages if (path.EndsWith("/")) path = path.Substring(0, path.Length - 1); - if (PageState == null || reload == Reload.Site) + if (PageState == null || refresh == UI.Refresh.Site) { page = pages.FirstOrDefault(item => item.Path.Equals(path, StringComparison.OrdinalIgnoreCase)); } @@ -264,7 +274,7 @@ { page = await ProcessPage(page, site, user); - if (PageState == null || reload == Reload.Site) + if (PageState == null || refresh == UI.Refresh.Site) { modules = await ModuleService.GetModulesAsync(site.SiteId); } diff --git a/Oqtane.Client/_Imports.razor b/Oqtane.Client/_Imports.razor index cbf43e76..45403934 100644 --- a/Oqtane.Client/_Imports.razor +++ b/Oqtane.Client/_Imports.razor @@ -10,6 +10,7 @@ @using Microsoft.Extensions.Localization @using Microsoft.JSInterop +@using Oqtane.Client @using Oqtane.Models @using Oqtane.Modules @using Oqtane.Modules.Controls @@ -22,3 +23,4 @@ @using Oqtane.UI @using Oqtane.Enums @using Oqtane.Installer +@using Oqtane.Interfaces diff --git a/Oqtane.Databases.sln b/Oqtane.Databases.sln index 379afe97..67deb124 100644 --- a/Oqtane.Databases.sln +++ b/Oqtane.Databases.sln @@ -18,6 +18,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Oqtane.Database.Sqlite", "O EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Oqtane.Database.SqlServer", "Oqtane.Database.SqlServer\Oqtane.Database.SqlServer.csproj", "{033DCA37-6354-4A3D-8250-4EC20740EE19}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Oqtane.Server", "Oqtane.Server\Oqtane.Server.csproj", "{6A60C4DD-67E6-42A7-B9AA-A1EE45AD45C7}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -40,6 +42,10 @@ Global {033DCA37-6354-4A3D-8250-4EC20740EE19}.Debug|Any CPU.Build.0 = Debug|Any CPU {033DCA37-6354-4A3D-8250-4EC20740EE19}.Release|Any CPU.ActiveCfg = Release|Any CPU {033DCA37-6354-4A3D-8250-4EC20740EE19}.Release|Any CPU.Build.0 = Release|Any CPU + {6A60C4DD-67E6-42A7-B9AA-A1EE45AD45C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6A60C4DD-67E6-42A7-B9AA-A1EE45AD45C7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6A60C4DD-67E6-42A7-B9AA-A1EE45AD45C7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6A60C4DD-67E6-42A7-B9AA-A1EE45AD45C7}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Oqtane.Server/Controllers/AliasController.cs b/Oqtane.Server/Controllers/AliasController.cs index a61f2ed4..644fa278 100644 --- a/Oqtane.Server/Controllers/AliasController.cs +++ b/Oqtane.Server/Controllers/AliasController.cs @@ -72,7 +72,7 @@ namespace Oqtane.Controllers [Authorize(Roles = RoleNames.Host)] public Alias Put(int id, [FromBody] Alias alias) { - if (ModelState.IsValid) + if (ModelState.IsValid && _aliases.GetAlias(alias.AliasId, false) != null) { alias = _aliases.UpdateAlias(alias); _logger.Log(LogLevel.Information, this, LogFunction.Update, "Alias Updated {Alias}", alias); @@ -91,8 +91,17 @@ namespace Oqtane.Controllers [Authorize(Roles = RoleNames.Host)] public void Delete(int id) { - _aliases.DeleteAlias(id); - _logger.Log(LogLevel.Information, this, LogFunction.Delete, "Alias Deleted {AliasId}", id); + var alias = _aliases.GetAlias(id); + if (alias != null) + { + _aliases.DeleteAlias(id); + _logger.Log(LogLevel.Information, this, LogFunction.Delete, "Alias Deleted {AliasId}", id); + } + else + { + _logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Alias Delete Attempt {AliasId}", id); + HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden; + } } } } diff --git a/Oqtane.Server/Controllers/InstallationController.cs b/Oqtane.Server/Controllers/InstallationController.cs index cf4f7048..dc51076f 100644 --- a/Oqtane.Server/Controllers/InstallationController.cs +++ b/Oqtane.Server/Controllers/InstallationController.cs @@ -15,6 +15,7 @@ using Microsoft.Extensions.Caching.Memory; using System.Net; using Oqtane.Repository; using Microsoft.AspNetCore.Http; +using System.Diagnostics; namespace Oqtane.Controllers { @@ -130,7 +131,7 @@ namespace Oqtane.Controllers } else { - Console.WriteLine($"The satellite assemblies folder named '{culture}' is not found."); + Debug.WriteLine($"Oqtane Error: The Satellite Assembly Folder For {culture} Does Not Exist"); } } @@ -148,7 +149,7 @@ namespace Oqtane.Controllers } else { - Console.WriteLine("Module " + instance.ModuleDefinition.ModuleDefinitionName + " dependency " + name + ".dll does not exist"); + Debug.WriteLine($"Oqtane Error: Module {instance.ModuleDefinition.ModuleDefinitionName} Dependency {name}.dll Does Not Exist"); } } } @@ -163,7 +164,7 @@ namespace Oqtane.Controllers } else { - Console.WriteLine("Theme " + instance.Theme.ThemeName + " dependency " + name + ".dll does not exist" ); + Debug.WriteLine($"Oqtane Error: Theme {instance.Theme.ThemeName} Dependency {name}.dll Does Not Exist"); } } } diff --git a/Oqtane.Server/Controllers/JobController.cs b/Oqtane.Server/Controllers/JobController.cs index db4f4bfb..356fd75f 100644 --- a/Oqtane.Server/Controllers/JobController.cs +++ b/Oqtane.Server/Controllers/JobController.cs @@ -9,6 +9,7 @@ using Microsoft.Extensions.DependencyInjection; using Oqtane.Enums; using Oqtane.Infrastructure; using Oqtane.Repository; +using System.Net; namespace Oqtane.Controllers { @@ -52,6 +53,12 @@ namespace Oqtane.Controllers job = _jobs.AddJob(job); _logger.Log(LogLevel.Information, this, LogFunction.Create, "Job Added {Job}", job); } + else + { + _logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Job Post Attempt {Alias}", job); + HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden; + job = null; + } return job; } @@ -60,11 +67,17 @@ namespace Oqtane.Controllers [Authorize(Roles = RoleNames.Host)] public Job Put(int id, [FromBody] Job job) { - if (ModelState.IsValid) + if (ModelState.IsValid && _jobs.GetJob(job.JobId, false) != null) { job = _jobs.UpdateJob(job); _logger.Log(LogLevel.Information, this, LogFunction.Update, "Job Updated {Job}", job); } + else + { + _logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Job Put Attempt {Alias}", job); + HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden; + job = null; + } return job; } @@ -73,8 +86,17 @@ namespace Oqtane.Controllers [Authorize(Roles = RoleNames.Host)] public void Delete(int id) { - _jobs.DeleteJob(id); - _logger.Log(LogLevel.Information, this, LogFunction.Delete, "Job Deleted {JobId}", id); + var job = _jobs.GetJob(id); + if (job != null) + { + _jobs.DeleteJob(id); + _logger.Log(LogLevel.Information, this, LogFunction.Delete, "Job Deleted {JobId}", id); + } + else + { + _logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Job Delete Attempt {JobId}", id); + HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden; + } } // GET api/