From b0af00aa47d35039d44db2de014c48c18ac30b57 Mon Sep 17 00:00:00 2001 From: Jim Spillane Date: Wed, 27 May 2020 16:58:50 -0400 Subject: [PATCH 01/11] Fix Alias route Added wildcard route catchall. --- Oqtane.Server/Controllers/AliasController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Oqtane.Server/Controllers/AliasController.cs b/Oqtane.Server/Controllers/AliasController.cs index 0bbdde97..c4422587 100644 --- a/Oqtane.Server/Controllers/AliasController.cs +++ b/Oqtane.Server/Controllers/AliasController.cs @@ -47,7 +47,7 @@ namespace Oqtane.Controllers } // GET api//name/xxx?sync=yyyyMMddHHmmssfff - [HttpGet("name/{name}")] + [HttpGet("name/{**name}")] public Alias Get(string name, string sync) { List aliases = _aliases.GetAliases().ToList(); // cached From e935451d934ceaabf13e1b2d716e6bd145ac734b Mon Sep 17 00:00:00 2001 From: Pavel Vesely Date: Thu, 28 May 2020 11:32:24 +0200 Subject: [PATCH 02/11] Search in User management --- Oqtane.Client/Modules/Admin/Users/Index.razor | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Users/Index.razor b/Oqtane.Client/Modules/Admin/Users/Index.razor index a9d4366f..cf180d73 100644 --- a/Oqtane.Client/Modules/Admin/Users/Index.razor +++ b/Oqtane.Client/Modules/Admin/Users/Index.razor @@ -9,7 +9,11 @@ } else { - + + +
+ +
@@ -28,16 +32,32 @@ else } @code { + private List allroles; private List userroles; + private string search; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; protected override async Task OnInitializedAsync() { - userroles = await UserRoleService.GetUserRolesAsync(PageState.Site.SiteId); - userroles = userroles.Where(item => item.Role.Name == Constants.RegisteredRole).ToList(); + allroles = await UserRoleService.GetUserRolesAsync(PageState.Site.SiteId); + userroles = allroles.Where(item => item.Role.Name == Constants.RegisteredRole).ToList(); } + private void OnSearch() + { + userroles = allroles + .Where(item => item.Role.Name == Constants.RegisteredRole && + ( + item.User.Username.Contains(search, StringComparison.OrdinalIgnoreCase) || + item.User.Email.Contains(search, StringComparison.OrdinalIgnoreCase) || + item.User.DisplayName.Contains(search, StringComparison.OrdinalIgnoreCase) + ) + ) + .ToList(); + } + + private async Task DeleteUser(UserRole UserRole) { try @@ -56,4 +76,4 @@ else AddModuleMessage(ex.Message, MessageType.Error); } } -} \ No newline at end of file +} From 151e37c4702bfbd3c056bedb3ba6aa643fe7f9ca Mon Sep 17 00:00:00 2001 From: Pavel Vesely Date: Thu, 28 May 2020 12:26:23 +0200 Subject: [PATCH 03/11] Uri extensions for read query values - safe way to check if key is presented - safe parsing int values in query - should replace int.Parse() _jobId = Int32.Parse(PageState.QueryString["id"]); can throw unhandled exception when "id" is not int correct way if (PageState.Uri.TryGetQueryValueInt("id",out _jobId)) .... --- Oqtane.Shared/Shared/Utilities.cs | 89 +++++++++++++++++++++++++------ 1 file changed, 74 insertions(+), 15 deletions(-) diff --git a/Oqtane.Shared/Shared/Utilities.cs b/Oqtane.Shared/Shared/Utilities.cs index de81561b..04f3ea1e 100644 --- a/Oqtane.Shared/Shared/Utilities.cs +++ b/Oqtane.Shared/Shared/Utilities.cs @@ -1,5 +1,6 @@ using Oqtane.Models; using System; +using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; @@ -15,7 +16,7 @@ namespace Oqtane.Shared { if (type == null) return null; var assemblyFullName = type.Assembly.FullName; - var assemblyName = assemblyFullName.Substring(0, assemblyFullName.IndexOf(",", StringComparison.Ordinal)); + var assemblyName = assemblyFullName.Substring(0, assemblyFullName.IndexOf(",", StringComparison.Ordinal)); return $"{type.Namespace}, {assemblyName}"; } @@ -24,10 +25,10 @@ namespace Oqtane.Shared var uriBuilder = new UriBuilder { Path = !string.IsNullOrEmpty(alias) - ? (!string.IsNullOrEmpty(path)) - ? $"{alias}/{path}" - : $"{alias}" - : $"{path}", + ? (!string.IsNullOrEmpty(path)) + ? $"{alias}/{path}" + : $"{alias}" + : $"{path}", Query = parameters }; @@ -44,6 +45,7 @@ namespace Oqtane.Shared path += $"/{action}"; } } + return NavigateUrl(alias, path, parameters); } @@ -98,6 +100,7 @@ namespace Oqtane.Shared // remove assembly if fully qualified type typename = typename.Substring(0, typename.IndexOf(",")); } + // segment 0 is the last segment, segment 1 is the second to last segment, etc... string[] segments = typename.Split('.'); string name = ""; @@ -105,6 +108,7 @@ namespace Oqtane.Shared { name = segments[segments.Length - (segment + 1)]; } + return name; } @@ -142,11 +146,14 @@ namespace Oqtane.Shared stringBuilder.Append('-'); prevdash = true; } + break; } } + result = stringBuilder.ToString().Trim('-'); } + return result; } @@ -236,25 +243,28 @@ namespace Oqtane.Shared if (string.IsNullOrEmpty(email)) return false; return Regex.IsMatch(email, - @"^(?("")("".+?(? ParseQueryString(string query) + { + Dictionary dictionary = new Dictionary(); + if (!string.IsNullOrEmpty(query)) + { + query = query.Substring(1); + string str = query; + char[] separator = new char[1] {'&'}; + foreach (string key in str.Split(separator, StringSplitOptions.RemoveEmptyEntries)) + { + if (key != "") + { + if (key.Contains("=")) + { + string[] strArray = key.Split('=', StringSplitOptions.None); + dictionary.Add(strArray[0], strArray[1]); + } + else + dictionary.Add(key, "true"); + } + } + } + + return dictionary; + } } } From 612a820dacc6d9eefd2dd14215ff9aff14bbb251 Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Thu, 28 May 2020 09:44:41 -0400 Subject: [PATCH 04/11] fixed stylesheet and script removal logic --- Oqtane.Client/UI/ThemeBuilder.razor | 9 +++++---- Oqtane.Server/wwwroot/js/interop.js | 9 +++++++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Oqtane.Client/UI/ThemeBuilder.razor b/Oqtane.Client/UI/ThemeBuilder.razor index 2b40e59e..792572b8 100644 --- a/Oqtane.Client/UI/ThemeBuilder.razor +++ b/Oqtane.Client/UI/ThemeBuilder.razor @@ -24,6 +24,7 @@ } // include page resources + string batch = DateTime.Now.ToString("yyyyMMddHHmmssfff"); var links = new List(); var scripts = new List(); foreach (Resource resource in PageState.Page.Resources) @@ -31,18 +32,18 @@ switch (resource.ResourceType) { case ResourceType.Stylesheet: - links.Add(new { id = "app-stylesheet" + links.Count.ToString("00"), rel = "stylesheet", href = resource.Url, type = "text/css", integrity = resource.Integrity ?? "", crossorigin = resource.CrossOrigin ?? "", key = "" }); + links.Add(new { id = "app-stylesheet-" + batch + "-" + (links.Count + 1).ToString("00"), rel = "stylesheet", href = resource.Url, type = "text/css", integrity = resource.Integrity ?? "", crossorigin = resource.CrossOrigin ?? "", key = "" }); break; case ResourceType.Script: - scripts.Add(new { id = "app-script" + scripts.Count.ToString("00"), src = resource.Url, integrity = resource.Integrity ?? "", crossorigin = resource.CrossOrigin ?? "", content = "", location = "body", key = "" }); + scripts.Add(new { id = "app-script-" + batch + "-" + (scripts.Count + 1).ToString("00"), src = resource.Url, integrity = resource.Integrity ?? "", crossorigin = resource.CrossOrigin ?? "", content = "", location = "body", key = "" }); break; } } await interop.IncludeLinks(links.ToArray()); await interop.IncludeScripts(scripts.ToArray()); // remove any page resource references which are no longer required for this page - await interop.RemoveElementsById("app-stylesheet", "app-stylesheet" + links.Count.ToString("00"), ""); - await interop.RemoveElementsById("app-script", "app-script" + scripts.Count.ToString("00"), ""); + await interop.RemoveElementsById("app-stylesheet", "", "app-stylesheet-" + batch + "-00"); + await interop.RemoveElementsById("app-script", "", "app-script-" + batch + "-00"); // add favicon if (PageState.Site.FaviconFileId != null) diff --git a/Oqtane.Server/wwwroot/js/interop.js b/Oqtane.Server/wwwroot/js/interop.js index f94c3472..90668589 100644 --- a/Oqtane.Server/wwwroot/js/interop.js +++ b/Oqtane.Server/wwwroot/js/interop.js @@ -45,6 +45,9 @@ Oqtane.Interop = { document.head.appendChild(meta); } else { + if (id !== "") { + meta.setAttribute("id", id); + } if (meta.content !== content) { meta.setAttribute("content", content); } @@ -77,6 +80,9 @@ Oqtane.Interop = { document.head.appendChild(link); } else { + if (link.id !== id) { + link.setAttribute('id', id); + } if (link.rel !== rel) { link.setAttribute('rel', rel); } @@ -148,6 +154,9 @@ Oqtane.Interop = { }); } else { + if (script.id !== id) { + script.setAttribute('id', id); + } if (src !== "") { if (script.src !== this.getAbsoluteUrl(src)) { script.removeAttribute('integrity'); From f7470e3c5b30922db676ebee7bbdc4301e6c6fc4 Mon Sep 17 00:00:00 2001 From: Pavel Vesely Date: Thu, 28 May 2020 20:00:28 +0200 Subject: [PATCH 05/11] Horizontal menu fix --- Oqtane.Client/Themes/Controls/MenuHorizontal.Razor | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Oqtane.Client/Themes/Controls/MenuHorizontal.Razor b/Oqtane.Client/Themes/Controls/MenuHorizontal.Razor index 8924054f..58159b13 100644 --- a/Oqtane.Client/Themes/Controls/MenuHorizontal.Razor +++ b/Oqtane.Client/Themes/Controls/MenuHorizontal.Razor @@ -16,7 +16,7 @@ if (p.PageId == PageState.Page.PageId) {