diff --git a/LICENSE b/LICENSE index 81e8cb41..9866f46b 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2018-2022 .NET Foundation +Copyright (c) 2018-2023 .NET Foundation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Oqtane.Client/Extensions/OqtaneServiceCollectionExtensions.cs b/Oqtane.Client/Extensions/OqtaneServiceCollectionExtensions.cs index d34aa575..bc1d4780 100644 --- a/Oqtane.Client/Extensions/OqtaneServiceCollectionExtensions.cs +++ b/Oqtane.Client/Extensions/OqtaneServiceCollectionExtensions.cs @@ -49,7 +49,6 @@ namespace Microsoft.Extensions.DependencyInjection services.AddScoped(); services.AddScoped(); services.AddScoped(); - services.AddScoped(); return services; } diff --git a/Oqtane.Client/Modules/Admin/Api/Edit.razor b/Oqtane.Client/Modules/Admin/Api/Edit.razor deleted file mode 100644 index e451fec8..00000000 --- a/Oqtane.Client/Modules/Admin/Api/Edit.razor +++ /dev/null @@ -1,75 +0,0 @@ -@namespace Oqtane.Modules.Admin.Apis -@inherits ModuleBase -@inject IApiService ApiService -@inject NavigationManager NavigationManager -@inject IStringLocalizer Localizer -@inject IStringLocalizer SharedLocalizer - -
-
- -
- -
-
-
-
- @if (_permissions != null) - { - - } -
-
- -@SharedLocalizer["Cancel"] - -@code { - private string _entityname; - private string _permissionnames; - private string _permissions; - -#pragma warning disable 649 - private PermissionGrid _permissionGrid; -#pragma warning restore 649 - - public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; - - protected override async Task OnInitializedAsync() - { - try - { - _entityname = PageState.QueryString["entity"]; - var api = await ApiService.GetApiAsync(PageState.Site.SiteId, _entityname); - if (api != null) - { - var apis = await ApiService.GetApisAsync(PageState.Site.SiteId); - _permissionnames = apis.SingleOrDefault(item => item.EntityName == _entityname).Permissions; - _permissions = api.Permissions; - } - } - catch (Exception ex) - { - await logger.LogError(ex, "Error Loading API {EntityName} {Error}", _entityname, ex.Message); - AddModuleMessage(Localizer["Error.Module.Load"], MessageType.Error); - } - } - - private async Task SaveModuleDefinition() - { - try - { - var api = new Api(); - api.SiteId = PageState.Site.SiteId; - api.EntityName = _entityname; - api.Permissions = _permissionGrid.GetPermissions(); - await ApiService.UpdateApiAsync(api); - await logger.LogInformation("API Saved {Api}", api); - NavigationManager.NavigateTo(NavigateUrl()); - } - catch (Exception ex) - { - await logger.LogError(ex, "Error Saving Api {EntityName} {Error}", _entityname, ex.Message); - AddModuleMessage(Localizer["Error.Module.Save"], MessageType.Error); - } - } -} diff --git a/Oqtane.Client/Modules/Admin/Api/Index.razor b/Oqtane.Client/Modules/Admin/Api/Index.razor deleted file mode 100644 index 539a8479..00000000 --- a/Oqtane.Client/Modules/Admin/Api/Index.razor +++ /dev/null @@ -1,36 +0,0 @@ -@namespace Oqtane.Modules.Admin.Apis -@inherits ModuleBase -@inject IApiService ApiService -@inject IStringLocalizer Localizer -@inject IStringLocalizer SharedLocalizer - -@if (_apis == null) -{ -

@SharedLocalizer["Loading"]

-} -else -{ - -
-   - @Localizer["Entity"] - @Localizer["Permissions"] -
- - - @context.EntityName - @context.Permissions - -
-} - -@code { - private List _apis; - - public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; - - protected override async Task OnParametersSetAsync() - { - _apis = await ApiService.GetApisAsync(PageState.Site.SiteId); - } -} diff --git a/Oqtane.Client/Modules/Admin/Dashboard/Index.razor b/Oqtane.Client/Modules/Admin/Dashboard/Index.razor index 97127ba3..e491042a 100644 --- a/Oqtane.Client/Modules/Admin/Dashboard/Index.razor +++ b/Oqtane.Client/Modules/Admin/Dashboard/Index.razor @@ -20,13 +20,16 @@ @code { - private List _pages; + private List _pages; - public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous; - protected override void OnInitialized() - { - var admin = PageState.Pages.FirstOrDefault(item => item.Path == "admin"); - _pages = PageState.Pages.Where(item => item.ParentId == admin?.PageId).ToList(); + protected override void OnInitialized() + { + var admin = PageState.Pages.FirstOrDefault(item => item.Path == "admin"); + if (admin != null) + { + _pages = PageState.Pages.Where(item => item.ParentId == admin?.PageId).ToList(); + } } } diff --git a/Oqtane.Client/Modules/Admin/Login/Index.razor b/Oqtane.Client/Modules/Admin/Login/Index.razor index d237190b..22fa249f 100644 --- a/Oqtane.Client/Modules/Admin/Login/Index.razor +++ b/Oqtane.Client/Modules/Admin/Login/Index.razor @@ -1,3 +1,4 @@ +@using System.Net @namespace Oqtane.Modules.Admin.Login @inherits ModuleBase @inject NavigationManager NavigationManager @@ -205,7 +206,7 @@ var authstateprovider = (IdentityAuthenticationStateProvider)ServiceProvider .GetService(typeof(IdentityAuthenticationStateProvider)); authstateprovider.NotifyAuthenticationChanged(); - NavigationManager.NavigateTo(NavigateUrl(_returnUrl, true)); + NavigationManager.NavigateTo(NavigateUrl(WebUtility.UrlDecode(_returnUrl), true)); } else { diff --git a/Oqtane.Client/Modules/Admin/Logs/Index.razor b/Oqtane.Client/Modules/Admin/Logs/Index.razor index d763a5de..79f2a7b9 100644 --- a/Oqtane.Client/Modules/Admin/Logs/Index.razor +++ b/Oqtane.Client/Modules/Admin/Logs/Index.razor @@ -106,12 +106,6 @@ else { try { - // external link to log item will display Details component - if (PageState.QueryString.ContainsKey("id") && int.TryParse(PageState.QueryString["id"], out int id)) - { - NavigationManager.NavigateTo(EditUrl(PageState.Page.Path, ModuleState.ModuleId, "Detail", $"/{id}")); - } - if (UrlParameters.ContainsKey("level")) { _level = UrlParameters["level"]; @@ -241,4 +235,15 @@ else _page = page; } + protected override void OnAfterRender(bool firstRender) + { + if (firstRender) + { + // external link to log item will display Details component + if (PageState.QueryString.ContainsKey("id") && int.TryParse(PageState.QueryString["id"], out int id)) + { + NavigationManager.NavigateTo(EditUrl(PageState.Page.Path, ModuleState.ModuleId, "Detail", $"/{id}")); + } + } + } } diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor b/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor index 65e99da5..bd5689f6 100644 --- a/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor @@ -131,7 +131,7 @@ else moduleDefinition = await ModuleDefinitionService.CreateModuleDefinitionAsync(moduleDefinition); var settings = await SettingService.GetModuleSettingsAsync(ModuleState.ModuleId); - SettingService.SetSetting(settings, "ModuleDefinitionName", moduleDefinition.ModuleDefinitionName); + settings = SettingService.SetSetting(settings, "ModuleDefinitionName", moduleDefinition.ModuleDefinitionName); await SettingService.UpdateModuleSettingsAsync(settings, ModuleState.ModuleId); GetLocation(); @@ -174,7 +174,7 @@ else private bool IsValid(string name) { // must contain letters, underscores and digits and first character must be letter or underscore - return !string.IsNullOrEmpty(name) && name.ToLower() != "module" && Regex.IsMatch(name, "^[A-Za-z_][A-Za-z0-9_]*$"); + return !string.IsNullOrEmpty(name) && name.ToLower() != "module" && !name.ToLower().Contains("oqtane") && Regex.IsMatch(name, "^[A-Za-z_][A-Za-z0-9_]*$"); } private void TemplateChanged(ChangeEventArgs e) diff --git a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Create.razor b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Create.razor index 78aac9fa..c1c50169 100644 --- a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Create.razor +++ b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Create.razor @@ -139,7 +139,7 @@ private bool IsValid(string name) { // must contain letters, underscores and digits and first character must be letter or underscore - return !string.IsNullOrEmpty(name) && name.ToLower() != "module" && Regex.IsMatch(name, "^[A-Za-z_][A-Za-z0-9_]*$"); + return !string.IsNullOrEmpty(name) && name.ToLower() != "module" && !name.ToLower().Contains("oqtane") && Regex.IsMatch(name, "^[A-Za-z_][A-Za-z0-9_]*$"); } private void TemplateChanged(ChangeEventArgs e) diff --git a/Oqtane.Client/Modules/Admin/Pages/Add.razor b/Oqtane.Client/Modules/Admin/Pages/Add.razor index de004f44..bd0cd704 100644 --- a/Oqtane.Client/Modules/Admin/Pages/Add.razor +++ b/Oqtane.Client/Modules/Admin/Pages/Add.razor @@ -157,7 +157,8 @@ } - +
+ diff --git a/Oqtane.Client/Modules/Admin/Pages/Edit.razor b/Oqtane.Client/Modules/Admin/Pages/Edit.razor index 23db89db..144a4dad 100644 --- a/Oqtane.Client/Modules/Admin/Pages/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Pages/Edit.razor @@ -148,7 +148,8 @@ -

+
+
} @@ -189,7 +190,8 @@
} - +
+ diff --git a/Oqtane.Client/Modules/Admin/Profiles/ModuleInfo.cs b/Oqtane.Client/Modules/Admin/Profiles/ModuleInfo.cs new file mode 100644 index 00000000..3aac2e6f --- /dev/null +++ b/Oqtane.Client/Modules/Admin/Profiles/ModuleInfo.cs @@ -0,0 +1,20 @@ +using Oqtane.Documentation; +using Oqtane.Models; +using Oqtane.Shared; + +namespace Oqtane.Modules.Admin.Profiles +{ + [PrivateApi("Mark this as private, since it's not very useful in the public docs")] + public class ModuleInfo : IModule + { + public ModuleDefinition ModuleDefinition => new ModuleDefinition + { + Name = "Profiles", + Description = "Manage Profiles", + Categories = "Admin", + Version = Constants.Version, + PermissionNames = $"{PermissionNames.View},{PermissionNames.Edit}," + + $"{EntityNames.Profile}:{PermissionNames.Write}:{RoleNames.Admin}" + }; + } +} diff --git a/Oqtane.Client/Modules/Admin/Roles/Add.razor b/Oqtane.Client/Modules/Admin/Roles/Add.razor index f20a721d..9116cfe7 100644 --- a/Oqtane.Client/Modules/Admin/Roles/Add.razor +++ b/Oqtane.Client/Modules/Admin/Roles/Add.razor @@ -42,7 +42,7 @@ private string _description = string.Empty; private string _isautoassigned = "False"; - public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit; private async Task SaveRole() { diff --git a/Oqtane.Client/Modules/Admin/Roles/Edit.razor b/Oqtane.Client/Modules/Admin/Roles/Edit.razor index b217acce..3da2f6ad 100644 --- a/Oqtane.Client/Modules/Admin/Roles/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Roles/Edit.razor @@ -49,7 +49,7 @@ private string _modifiedby; private DateTime _modifiedon; - public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit; protected override async Task OnInitializedAsync() { diff --git a/Oqtane.Client/Modules/Admin/Roles/Index.razor b/Oqtane.Client/Modules/Admin/Roles/Index.razor index 2bb4ac87..6677548d 100644 --- a/Oqtane.Client/Modules/Admin/Roles/Index.razor +++ b/Oqtane.Client/Modules/Admin/Roles/Index.razor @@ -10,7 +10,7 @@ } else { - +
@@ -20,9 +20,9 @@ else @SharedLocalizer["Name"]
- - - + + + @context.Name
@@ -31,7 +31,7 @@ else @code { private List _roles; - public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.View; protected override async Task OnParametersSetAsync() { diff --git a/Oqtane.Client/Modules/Admin/Roles/ModuleInfo.cs b/Oqtane.Client/Modules/Admin/Roles/ModuleInfo.cs new file mode 100644 index 00000000..de80be0a --- /dev/null +++ b/Oqtane.Client/Modules/Admin/Roles/ModuleInfo.cs @@ -0,0 +1,21 @@ +using Oqtane.Documentation; +using Oqtane.Models; +using Oqtane.Shared; + +namespace Oqtane.Modules.Admin.Roles +{ + [PrivateApi("Mark this as private, since it's not very useful in the public docs")] + public class ModuleInfo : IModule + { + public ModuleDefinition ModuleDefinition => new ModuleDefinition + { + Name = "Roles", + Description = "Manage Roles", + Categories = "Admin", + Version = Constants.Version, + PermissionNames = $"{PermissionNames.View},{PermissionNames.Edit}," + + $"{EntityNames.Role}:{PermissionNames.Write}:{RoleNames.Admin}," + + $"{EntityNames.UserRole}:{PermissionNames.Write}:{RoleNames.Admin}" + }; + } +} diff --git a/Oqtane.Client/Modules/Admin/Roles/Users.razor b/Oqtane.Client/Modules/Admin/Roles/Users.razor index 359bc113..d0eb0aac 100644 --- a/Oqtane.Client/Modules/Admin/Roles/Users.razor +++ b/Oqtane.Client/Modules/Admin/Roles/Users.razor @@ -23,13 +23,7 @@ else
- +
@@ -64,7 +58,7 @@ else @context.EffectiveDate @context.ExpiryDate - + @@ -75,81 +69,96 @@ else } @code { - private ElementReference form; - private bool validated = false; + private ElementReference form; + private bool validated = false; - private int roleid; - private string name = string.Empty; - private List users; - private int userid = -1; - private DateTime? effectivedate = null; - private DateTime? expirydate = null; - private List userroles; + private int roleid; + private string name = string.Empty; + private AutoComplete user; + private DateTime? effectivedate = null; + private DateTime? expirydate = null; + private List userroles; - public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit; - protected override async Task OnInitializedAsync() - { - try - { - roleid = Int32.Parse(PageState.QueryString["id"]); - Role role = await RoleService.GetRoleAsync(roleid); - name = role.Name; - users = await UserRoleService.GetUserRolesAsync(PageState.Site.SiteId, RoleNames.Registered); - await GetUserRoles(); - } - catch (Exception ex) - { - await logger.LogError(ex, "Error Loading Users {Error}", ex.Message); - AddModuleMessage(Localizer["Error.User.Load"], MessageType.Error); - } - } + protected override async Task OnInitializedAsync() + { + try + { + roleid = Int32.Parse(PageState.QueryString["id"]); + Role role = await RoleService.GetRoleAsync(roleid); + name = role.Name; + await GetUserRoles(); + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Loading Users {Error}", ex.Message); + AddModuleMessage(Localizer["Error.User.Load"], MessageType.Error); + } + } - private async Task GetUserRoles() - { - try - { - userroles = await UserRoleService.GetUserRolesAsync(PageState.Site.SiteId, name); - } - catch (Exception ex) - { - await logger.LogError(ex, "Error Loading User Roles {RoleId} {Error}", roleid, ex.Message); - AddModuleMessage(Localizer["Error.User.LoadRole"], MessageType.Error); - } - } + private async Task> GetUsers(string filter) + { + try + { + var users = await UserRoleService.GetUserRolesAsync(PageState.Site.SiteId, RoleNames.Registered); + return users.Where(item => item.User.DisplayName.Contains(filter, StringComparison.OrdinalIgnoreCase)) + .ToDictionary(item => item.UserId.ToString(), item => item.User.DisplayName); + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Loading Users {filter} {Error}", filter, ex.Message); + AddModuleMessage(Localizer["Error.User.Load"], MessageType.Error); + } + return new Dictionary(); + } - private async Task SaveUserRole() - { - validated = true; - var interop = new Interop(JSRuntime); - if (await interop.FormValid(form)) - { - try - { - if (userid != -1) - { - var userrole = userroles.Where(item => item.UserId == userid && item.RoleId == roleid).FirstOrDefault(); - if (userrole != null) - { - userrole.EffectiveDate = effectivedate; - userrole.ExpiryDate = expirydate; - await UserRoleService.UpdateUserRoleAsync(userrole); - } - else - { - userrole = new UserRole(); - userrole.UserId = userid; - userrole.RoleId = roleid; - userrole.EffectiveDate = effectivedate; - userrole.ExpiryDate = expirydate; + private async Task GetUserRoles() + { + try + { + userroles = await UserRoleService.GetUserRolesAsync(PageState.Site.SiteId, name); + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Loading User Roles {RoleId} {Error}", roleid, ex.Message); + AddModuleMessage(Localizer["Error.User.LoadRole"], MessageType.Error); + } + } - await UserRoleService.AddUserRoleAsync(userrole); - } + private async Task SaveUserRole() + { + validated = true; + var interop = new Interop(JSRuntime); + if (await interop.FormValid(form)) + { + try + { + if (!string.IsNullOrEmpty(user.Key) && int.TryParse(user.Key, out int userid)) + { + var userrole = userroles.Where(item => item.UserId == userid && item.RoleId == roleid).FirstOrDefault(); + if (userrole != null) + { + userrole.EffectiveDate = effectivedate; + userrole.ExpiryDate = expirydate; + await UserRoleService.UpdateUserRoleAsync(userrole); + } + else + { + userrole = new UserRole(); + userrole.UserId = userid; + userrole.RoleId = roleid; + userrole.EffectiveDate = effectivedate; + userrole.ExpiryDate = expirydate; - await logger.LogInformation("User Assigned To Role {UserRole}", userrole); - AddModuleMessage(Localizer["Success.User.AssignedRole"], MessageType.Success); - await GetUserRoles(); - StateHasChanged(); + await UserRoleService.AddUserRoleAsync(userrole); + } + + await logger.LogInformation("User Assigned To Role {UserRole}", userrole); + AddModuleMessage(Localizer["Success.User.AssignedRole"], MessageType.Success); + await GetUserRoles(); + user.Clear(); + StateHasChanged(); } else { diff --git a/Oqtane.Client/Modules/Admin/Site/Index.razor b/Oqtane.Client/Modules/Admin/Site/Index.razor index 367d31de..bb9a7660 100644 --- a/Oqtane.Client/Modules/Admin/Site/Index.razor +++ b/Oqtane.Client/Modules/Admin/Site/Index.razor @@ -127,7 +127,7 @@
- +
@@ -142,12 +142,21 @@
- +
-
+
+ +
+ +
+
+
@@ -275,7 +284,10 @@
- +
+ + +
@@ -320,6 +332,7 @@ private string _smtppasswordtype = "password"; private string _togglesmtppassword = string.Empty; private string _smtpsender = string.Empty; + private string _smtprelay = "False"; private string _retention = string.Empty; private string _pwaisenabled; private int _pwaappiconfileid = -1; @@ -329,6 +342,8 @@ private string _tenant = string.Empty; private string _database = string.Empty; private string _connectionstring = string.Empty; + private string _connectionstringtype = "password"; + private string _connectionstringtoggle = string.Empty; private string _createdby; private DateTime _createdon; private string _modifiedby; @@ -343,6 +358,7 @@ { try { + _connectionstringtoggle = SharedLocalizer["ShowPassword"]; _themeList = await ThemeService.GetThemesAsync(); Site site = await SiteService.GetSiteAsync(PageState.Site.SiteId); if (site != null) @@ -393,6 +409,7 @@ _smtppassword = SettingService.GetSetting(settings, "SMTPPassword", string.Empty); _togglesmtppassword = SharedLocalizer["ShowPassword"]; _smtpsender = SettingService.GetSetting(settings, "SMTPSender", string.Empty); + _smtprelay = SettingService.GetSetting(settings, "SMTPRelay", "False"); _retention = SettingService.GetSetting(settings, "NotificationRetention", "30"); if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host)) @@ -449,6 +466,20 @@ } } + private void ToggleConnectionString() + { + if (_connectionstringtype == "password") + { + _connectionstringtype = "text"; + _connectionstringtoggle = SharedLocalizer["HidePassword"]; + } + else + { + _connectionstringtype = "password"; + _connectionstringtoggle = SharedLocalizer["ShowPassword"]; + } + } + private async Task SaveSite() { validated = true; @@ -532,6 +563,7 @@ settings = SettingService.SetSetting(settings, "SMTPUsername", _smtpusername, true); settings = SettingService.SetSetting(settings, "SMTPPassword", _smtppassword, true); settings = SettingService.SetSetting(settings, "SMTPSender", _smtpsender, true); + settings = SettingService.SetSetting(settings, "SMTPRelay", _smtprelay, true); settings = SettingService.SetSetting(settings, "NotificationRetention", _retention, true); await SettingService.UpdateSiteSettingsAsync(settings, site.SiteId); @@ -602,12 +634,12 @@ try { var settings = await SettingService.GetSiteSettingsAsync(PageState.Site.SiteId); - SettingService.SetSetting(settings, "SMTPHost", _smtphost, true); - SettingService.SetSetting(settings, "SMTPPort", _smtpport, true); - SettingService.SetSetting(settings, "SMTPSSL", _smtpssl, true); - SettingService.SetSetting(settings, "SMTPUsername", _smtpusername, true); - SettingService.SetSetting(settings, "SMTPPassword", _smtppassword, true); - SettingService.SetSetting(settings, "SMTPSender", _smtpsender, true); + settings = SettingService.SetSetting(settings, "SMTPHost", _smtphost, true); + settings = SettingService.SetSetting(settings, "SMTPPort", _smtpport, true); + settings = SettingService.SetSetting(settings, "SMTPSSL", _smtpssl, true); + settings = SettingService.SetSetting(settings, "SMTPUsername", _smtpusername, true); + settings = SettingService.SetSetting(settings, "SMTPPassword", _smtppassword, true); + settings = SettingService.SetSetting(settings, "SMTPSender", _smtpsender, true); await SettingService.UpdateSiteSettingsAsync(settings, PageState.Site.SiteId); await logger.LogInformation("Site SMTP Settings Saved"); diff --git a/Oqtane.Client/Modules/Admin/Sites/Add.razor b/Oqtane.Client/Modules/Admin/Sites/Add.razor index a8b7d495..509928f8 100644 --- a/Oqtane.Client/Modules/Admin/Sites/Add.razor +++ b/Oqtane.Client/Modules/Admin/Sites/Add.razor @@ -315,7 +315,7 @@ else _urls = Regex.Replace(_urls, @"\r\n?|\n", ","); var duplicates = new List(); var aliases = await AliasService.GetAliasesAsync(); - foreach (string name in _urls.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) + foreach (string name in _urls.Split(',', StringSplitOptions.RemoveEmptyEntries)) { if (aliases.Exists(item => item.Name == name)) { diff --git a/Oqtane.Client/Modules/Admin/Sql/Index.razor b/Oqtane.Client/Modules/Admin/Sql/Index.razor index 3e149596..c6bc3408 100644 --- a/Oqtane.Client/Modules/Admin/Sql/Index.razor +++ b/Oqtane.Client/Modules/Admin/Sql/Index.razor @@ -16,7 +16,7 @@ else
- +
+
} diff --git a/Oqtane.Client/Modules/Admin/SystemInfo/Index.razor b/Oqtane.Client/Modules/Admin/SystemInfo/Index.razor index 38291a66..239d3e9b 100644 --- a/Oqtane.Client/Modules/Admin/SystemInfo/Index.razor +++ b/Oqtane.Client/Modules/Admin/SystemInfo/Index.razor @@ -147,6 +147,18 @@ @Localizer["Access.ApiFramework"]  + +
+
+ +
+