From 7f978c7845fc8a5a6823cc54312e7da09fe3d1de Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Thu, 17 Oct 2024 13:52:21 -0400 Subject: [PATCH 01/38] Update README.md --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8e9d7884..a93ac330 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Latest Release -[5.2.3](https://github.com/oqtane/oqtane.framework/releases/tag/v5.2.3) was released on September 23, 2024 and is a maintenance release including 55 pull requests by 8 different contributors, pushing the total number of project commits all-time to over 5800. The Oqtane framework continues to evolve at a rapid pace to meet the needs of .NET developers. +[5.2.4](https://github.com/oqtane/oqtane.framework/releases/tag/v5.2.4) was released on October 17, 2024 and is a maintenance release including 51 pull requests by 7 different contributors, pushing the total number of project commits all-time to over 5900. The Oqtane framework continues to evolve at a rapid pace to meet the needs of .NET developers. [![Deploy to Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2Foqtane%2Foqtane.framework%2Fmaster%2Fazuredeploy.json) @@ -18,7 +18,7 @@ Please note that this project is owned by the .NET Foundation and is governed by **Installing using source code from the Dev/Master branch:** -- Install **[.NET 8.0.8 SDK](https://dotnet.microsoft.com/download/dotnet/8.0)**. +- Install **[.NET 8.0.10 SDK](https://dotnet.microsoft.com/download/dotnet/8.0)**. - Install the latest edition (v17.9 or higher) of [Visual Studio 2022](https://visualstudio.microsoft.com/downloads) with the **ASP.NET and web development** workload enabled. Oqtane works with ALL editions of Visual Studio from Community to Enterprise. If you wish to use LocalDB for development ( not a requirement as Oqtane supports SQLite, mySQL, and PostgreSQL ) you must also install the **Data storage and processing**. @@ -88,6 +88,9 @@ Backlog (TBD) - [ ] Azure Autoscale support (ie. web farm) - [ ] Folder Providers - [ ] Generative AI Integration + +[5.2.4](https://github.com/oqtane/oqtane.framework/releases/tag/v5.2.4) (Oct 17, 2024) +- [x] Stabilization improvements [5.2.3](https://github.com/oqtane/oqtane.framework/releases/tag/v5.2.3) (Sep 23, 2024) - [x] Stabilization improvements From 4f74962ce251048855ed7d9b97b7bdfcdf10f9a3 Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 21 Oct 2024 23:11:57 +0800 Subject: [PATCH 02/38] Fix #4752: validate the username and email. --- Oqtane.Client/Installer/Installer.razor | 205 +++++++++--------- .../Services/Interfaces/IUserService.cs | 9 + Oqtane.Client/Services/UserService.cs | 5 + Oqtane.Server/Controllers/UserController.cs | 7 + Oqtane.Server/Managers/InstallUserManager.cs | 41 ++++ .../Managers/Interfaces/IUserManager.cs | 1 + Oqtane.Server/Managers/UserManager.cs | 78 ++++++- Oqtane.Shared/Models/UserValidateResult.cs | 15 ++ 8 files changed, 258 insertions(+), 103 deletions(-) create mode 100644 Oqtane.Server/Managers/InstallUserManager.cs create mode 100644 Oqtane.Shared/Models/UserValidateResult.cs diff --git a/Oqtane.Client/Installer/Installer.razor b/Oqtane.Client/Installer/Installer.razor index 94f9cc39..20d4742e 100644 --- a/Oqtane.Client/Installer/Installer.razor +++ b/Oqtane.Client/Installer/Installer.razor @@ -156,129 +156,130 @@ private List _templates; private string _template = Constants.DefaultSiteTemplate; private bool _register = true; - private string _message = string.Empty; - private string _loadingDisplay = "display: none;"; + private string _message = string.Empty; + private string _loadingDisplay = "display: none;"; - protected override async Task OnInitializedAsync() - { + protected override async Task OnInitializedAsync() + { // include CSS var content = $""; SiteState.AppendHeadContent(content); _togglePassword = SharedLocalizer["ShowPassword"]; - _toggleConfirmPassword = SharedLocalizer["ShowPassword"]; + _toggleConfirmPassword = SharedLocalizer["ShowPassword"]; - _databases = await DatabaseService.GetDatabasesAsync(); - if (_databases.Exists(item => item.IsDefault)) - { - _databaseName = _databases.Find(item => item.IsDefault).Name; - } - else - { - _databaseName = "LocalDB"; - } - LoadDatabaseConfigComponent(); + _databases = await DatabaseService.GetDatabasesAsync(); + if (_databases.Exists(item => item.IsDefault)) + { + _databaseName = _databases.Find(item => item.IsDefault).Name; + } + else + { + _databaseName = "LocalDB"; + } + LoadDatabaseConfigComponent(); _templates = await SiteTemplateService.GetSiteTemplatesAsync(); } - private void DatabaseChanged(ChangeEventArgs eventArgs) - { - try - { - _databaseName = (string)eventArgs.Value; - _showConnectionString = false; - LoadDatabaseConfigComponent(); - } - catch - { - _message = Localizer["Error.DbConfig.Load"]; - } - } + private void DatabaseChanged(ChangeEventArgs eventArgs) + { + try + { + _databaseName = (string)eventArgs.Value; + _showConnectionString = false; + LoadDatabaseConfigComponent(); + } + catch + { + _message = Localizer["Error.DbConfig.Load"]; + } + } - private void LoadDatabaseConfigComponent() - { - var database = _databases.SingleOrDefault(d => d.Name == _databaseName); - if (database != null) - { - _databaseConfigType = Type.GetType(database.ControlType); - DatabaseConfigComponent = builder => - { - builder.OpenComponent(0, _databaseConfigType); - builder.AddComponentReferenceCapture(1, inst => { _databaseConfig = Convert.ChangeType(inst, _databaseConfigType); }); - builder.CloseComponent(); - }; - } - } + private void LoadDatabaseConfigComponent() + { + var database = _databases.SingleOrDefault(d => d.Name == _databaseName); + if (database != null) + { + _databaseConfigType = Type.GetType(database.ControlType); + DatabaseConfigComponent = builder => + { + builder.OpenComponent(0, _databaseConfigType); + builder.AddComponentReferenceCapture(1, inst => { _databaseConfig = Convert.ChangeType(inst, _databaseConfigType); }); + builder.CloseComponent(); + }; + } + } - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { // include JavaScript - var interop = new Interop(JSRuntime); + var interop = new Interop(JSRuntime); await interop.IncludeScript("", Constants.BootstrapScriptUrl, Constants.BootstrapScriptIntegrity, "anonymous", "", "head"); - } - } + } + } - private async Task Install() - { - var connectionString = String.Empty; - if (_showConnectionString) - { - connectionString = _connectionString; - } - else - { - if (_databaseConfig is IDatabaseConfigControl databaseConfigControl) - { - connectionString = databaseConfigControl.GetConnectionString(); - } - } + private async Task Install() + { + var connectionString = String.Empty; + if (_showConnectionString) + { + connectionString = _connectionString; + } + else + { + if (_databaseConfig is IDatabaseConfigControl databaseConfigControl) + { + connectionString = databaseConfigControl.GetConnectionString(); + } + } - if (connectionString != "" && !string.IsNullOrEmpty(_hostUsername) && !string.IsNullOrEmpty(_hostPassword) && _hostPassword == _confirmPassword && !string.IsNullOrEmpty(_hostEmail) && _hostEmail.Contains("@")) - { - if (await UserService.ValidatePasswordAsync(_hostPassword)) - { - _loadingDisplay = ""; - StateHasChanged(); + if (connectionString != "" && !string.IsNullOrEmpty(_hostUsername) && !string.IsNullOrEmpty(_hostPassword) && _hostPassword == _confirmPassword && !string.IsNullOrEmpty(_hostEmail) && _hostEmail.Contains("@")) + { + var result = await UserService.ValidateUserAsync(_hostUsername, _hostEmail, _hostPassword); + if (result.Succeeded) + { + _loadingDisplay = ""; + StateHasChanged(); - Uri uri = new Uri(NavigationManager.Uri); + Uri uri = new Uri(NavigationManager.Uri); - var database = _databases.SingleOrDefault(d => d.Name == _databaseName); + var database = _databases.SingleOrDefault(d => d.Name == _databaseName); - var config = new InstallConfig - { - DatabaseType = database.DBType, - ConnectionString = connectionString, - Aliases = uri.Authority, - HostUsername = _hostUsername, - HostPassword = _hostPassword, - HostEmail = _hostEmail, - HostName = _hostUsername, - TenantName = TenantNames.Master, - IsNewTenant = true, - SiteName = Constants.DefaultSite, - Register = _register, - SiteTemplate = _template, - RenderMode = RenderModes.Static, - Runtime = Runtimes.Server - }; + var config = new InstallConfig + { + DatabaseType = database.DBType, + ConnectionString = connectionString, + Aliases = uri.Authority, + HostUsername = _hostUsername, + HostPassword = _hostPassword, + HostEmail = _hostEmail, + HostName = _hostUsername, + TenantName = TenantNames.Master, + IsNewTenant = true, + SiteName = Constants.DefaultSite, + Register = _register, + SiteTemplate = _template, + RenderMode = RenderModes.Static, + Runtime = Runtimes.Server + }; - var installation = await InstallationService.Install(config); - if (installation.Success) - { - NavigationManager.NavigateTo(uri.Scheme + "://" + uri.Authority, true); - } - else - { - _message = installation.Message; - _loadingDisplay = "display: none;"; - } - } - else - { - _message = Localizer["Message.Password.Invalid"]; + var installation = await InstallationService.Install(config); + if (installation.Success) + { + NavigationManager.NavigateTo(uri.Scheme + "://" + uri.Authority, true); + } + else + { + _message = installation.Message; + _loadingDisplay = "display: none;"; + } + } + else + { + _message = string.Join("
", result.Errors.Select(i => i.Value)); } } else diff --git a/Oqtane.Client/Services/Interfaces/IUserService.cs b/Oqtane.Client/Services/Interfaces/IUserService.cs index 534466a5..b32a66f0 100644 --- a/Oqtane.Client/Services/Interfaces/IUserService.cs +++ b/Oqtane.Client/Services/Interfaces/IUserService.cs @@ -113,6 +113,15 @@ namespace Oqtane.Services /// Task VerifyTwoFactorAsync(User user, string token); + /// + /// Validate identity user info. + /// + /// + /// + /// + /// + Task ValidateUserAsync(string username, string email, string password); + /// /// Validate a users password against the password policy /// diff --git a/Oqtane.Client/Services/UserService.cs b/Oqtane.Client/Services/UserService.cs index 2133d2de..d69aa10d 100644 --- a/Oqtane.Client/Services/UserService.cs +++ b/Oqtane.Client/Services/UserService.cs @@ -89,6 +89,11 @@ namespace Oqtane.Services return await PostJsonAsync($"{Apiurl}/twofactor?token={token}", user); } + public async Task ValidateUserAsync(string username, string email, string password) + { + return await GetJsonAsync($"{Apiurl}/validateuser?username={WebUtility.UrlEncode(username)}&email={WebUtility.UrlEncode(email)}&password={WebUtility.UrlEncode(password)}"); + } + public async Task ValidatePasswordAsync(string password) { return await GetJsonAsync($"{Apiurl}/validate/{WebUtility.UrlEncode(password)}"); diff --git a/Oqtane.Server/Controllers/UserController.cs b/Oqtane.Server/Controllers/UserController.cs index 9e80be8d..acbcb1a1 100644 --- a/Oqtane.Server/Controllers/UserController.cs +++ b/Oqtane.Server/Controllers/UserController.cs @@ -347,6 +347,13 @@ namespace Oqtane.Controllers return user; } + // GET api//validate/x + [HttpGet("validateuser")] + public async Task ValidateUser(string username, string email, string password) + { + return await _userManager.ValidateUser(username, email, password); + } + // GET api//validate/x [HttpGet("validate/{password}")] public async Task Validate(string password) diff --git a/Oqtane.Server/Managers/InstallUserManager.cs b/Oqtane.Server/Managers/InstallUserManager.cs new file mode 100644 index 00000000..909b36e7 --- /dev/null +++ b/Oqtane.Server/Managers/InstallUserManager.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Identity; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; + +namespace Oqtane.Managers +{ + /// + /// This class is only used for user validation during installation process. + /// + /// + internal class InstallUserManager : UserManager + { + public InstallUserManager(IUserStore store, IOptions optionsAccessor, IPasswordHasher passwordHasher, IEnumerable> userValidators, IEnumerable> passwordValidators, ILookupNormalizer keyNormalizer, IdentityErrorDescriber errors, IServiceProvider services, ILogger> logger) : base(store, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors, services, logger) + { + } + + public override async Task FindByNameAsync(string userName) + { + await Task.CompletedTask; + + return null; + } + + public override async Task FindByEmailAsync(string email) + { + await Task.CompletedTask; + + return null; + } + + public override async Task GetUserIdAsync(IdentityUser user) + { + await Task.CompletedTask; + + return null; + } + } +} diff --git a/Oqtane.Server/Managers/Interfaces/IUserManager.cs b/Oqtane.Server/Managers/Interfaces/IUserManager.cs index 5ada9827..4fde062c 100644 --- a/Oqtane.Server/Managers/Interfaces/IUserManager.cs +++ b/Oqtane.Server/Managers/Interfaces/IUserManager.cs @@ -19,6 +19,7 @@ namespace Oqtane.Managers Task ResetPassword(User user, string token); User VerifyTwoFactor(User user, string token); Task LinkExternalAccount(User user, string token, string type, string key, string name); + Task ValidateUser(string username, string email, string password); Task ValidatePassword(string password); Task> ImportUsers(int siteId, string filePath, bool notify); } diff --git a/Oqtane.Server/Managers/UserManager.cs b/Oqtane.Server/Managers/UserManager.cs index e0e92e97..76e0c05d 100644 --- a/Oqtane.Server/Managers/UserManager.cs +++ b/Oqtane.Server/Managers/UserManager.cs @@ -33,8 +33,41 @@ namespace Oqtane.Managers private readonly ILogManager _logger; private readonly IMemoryCache _cache; private readonly IStringLocalizer _localizer; + private readonly IUserStore _identityStore; + private readonly Microsoft.Extensions.Options.IOptions _identityOptionsAccessor; + private readonly IPasswordHasher _passwordHasher; + private readonly IEnumerable> _userValidators; + private readonly IEnumerable> _passwordValidators; + private readonly ILookupNormalizer _identityKeyNormalizer; + private readonly IdentityErrorDescriber _identityErrors; + private readonly IServiceProvider _identityServices; + private readonly Microsoft.Extensions.Logging.ILogger> _identityLogger; - public UserManager(IUserRepository users, IRoleRepository roles, IUserRoleRepository userRoles, UserManager identityUserManager, SignInManager identitySignInManager, ITenantManager tenantManager, INotificationRepository notifications, IFolderRepository folders, IProfileRepository profiles, ISettingRepository settings, ISiteRepository sites, ISyncManager syncManager, ILogManager logger, IMemoryCache cache, IStringLocalizer localizer) + public UserManager( + IUserRepository users, + IRoleRepository roles, + IUserRoleRepository userRoles, + UserManager identityUserManager, + SignInManager identitySignInManager, + ITenantManager tenantManager, + INotificationRepository notifications, + IFolderRepository folders, + IProfileRepository profiles, + ISettingRepository settings, + ISiteRepository sites, + ISyncManager syncManager, + ILogManager logger, + IMemoryCache cache, + IStringLocalizer localizer, + IUserStore store, + Microsoft.Extensions.Options.IOptions optionsAccessor, + IPasswordHasher passwordHasher, + IEnumerable> userValidators, + IEnumerable> passwordValidators, + ILookupNormalizer keyNormalizer, + IdentityErrorDescriber errors, + IServiceProvider services, + Microsoft.Extensions.Logging.ILogger> identityLogger) { _users = users; _roles = roles; @@ -51,6 +84,15 @@ namespace Oqtane.Managers _logger = logger; _cache = cache; _localizer = localizer; + _identityStore = store; + _identityOptionsAccessor = optionsAccessor; + _passwordHasher = passwordHasher; + _userValidators = userValidators; + _passwordValidators = passwordValidators; + _identityKeyNormalizer = keyNormalizer; + _identityErrors = errors; + _identityServices = services; + _identityLogger = identityLogger; } public User GetUser(int userid, int siteid) @@ -540,6 +582,40 @@ namespace Oqtane.Managers return user; } + public async Task ValidateUser(string username, string email, string password) + { + var validateResult = new UserValidateResult { Succeeded = true }; + var installUserManager = new InstallUserManager(_identityStore, _identityOptionsAccessor, _passwordHasher, _userValidators, _passwordValidators, _identityKeyNormalizer, _identityErrors, _identityServices, _identityLogger); + + var user = new IdentityUser { UserName = username, Email = email, EmailConfirmed = true }; + var userValidator = new UserValidator(); + var userResult = await userValidator.ValidateAsync(installUserManager, user); + if (!userResult.Succeeded) + { + validateResult.Succeeded = false; + if(userResult.Errors != null) + { + validateResult.Errors = userResult.Errors?.ToDictionary(i => i.Code, i => i.Description); + } + } + + var passwordValidator = new PasswordValidator(); + var passwordResult = await passwordValidator.ValidateAsync(installUserManager, null, password); + if (!passwordResult.Succeeded && !validateResult.Errors.ContainsKey("InvalidPassword")) + { + validateResult.Succeeded = false; + if (passwordResult.Errors != null) + { + foreach (var error in passwordResult.Errors) + { + validateResult.Errors.Add(error.Code, error.Description); + } + } + } + + return validateResult; + } + public async Task ValidatePassword(string password) { var validator = new PasswordValidator(); diff --git a/Oqtane.Shared/Models/UserValidateResult.cs b/Oqtane.Shared/Models/UserValidateResult.cs new file mode 100644 index 00000000..d531ab82 --- /dev/null +++ b/Oqtane.Shared/Models/UserValidateResult.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Oqtane.Models +{ + public class UserValidateResult + { + public bool Succeeded { get; set; } + + public IDictionary Errors { get; set; } = new Dictionary(); + } +} From 23010acef4a8ff8c34ae2c4cb2819117695af02f Mon Sep 17 00:00:00 2001 From: Cody Date: Mon, 21 Oct 2024 10:36:12 -0700 Subject: [PATCH 03/38] Scroll to top after saving settings - Fixes #4758 --- Oqtane.Client/Modules/Admin/Users/Index.razor | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Oqtane.Client/Modules/Admin/Users/Index.razor b/Oqtane.Client/Modules/Admin/Users/Index.razor index a59b161d..a5211c55 100644 --- a/Oqtane.Client/Modules/Admin/Users/Index.razor +++ b/Oqtane.Client/Modules/Admin/Users/Index.razor @@ -691,6 +691,10 @@ else await logger.LogError(ex, "Error Saving Site Settings {Error}", ex.Message); AddModuleMessage(Localizer["Error.SaveSiteSettings"], MessageType.Error); } + finally + { + await ScrollToPageTop(); + } } private void ProviderChanged(ChangeEventArgs e) From 73ea17ae0f655f47d49f0f81a47ba936c4aabb34 Mon Sep 17 00:00:00 2001 From: sbwalker Date: Mon, 21 Oct 2024 14:51:20 -0400 Subject: [PATCH 04/38] changes to migrate Oqtane to .NET 9 and version 6.0.0 --- Oqtane.Client/Installer/Installer.razor | 2 +- Oqtane.Client/Oqtane.Client.csproj | 14 +++++----- .../Oqtane.Database.MySQL.csproj | 10 +++---- .../Oqtane.Database.PostgreSQL.csproj | 12 ++++---- .../Oqtane.Database.SqlServer.csproj | 10 +++---- .../Oqtane.Database.Sqlite.csproj | 10 +++---- Oqtane.Package/Oqtane.Client.nuspec | 8 +++--- Oqtane.Package/Oqtane.Framework.nuspec | 6 ++-- Oqtane.Package/Oqtane.Server.nuspec | 8 +++--- Oqtane.Package/Oqtane.Shared.nuspec | 8 +++--- Oqtane.Package/Oqtane.Updater.nuspec | 6 ++-- Oqtane.Package/install.ps1 | 2 +- Oqtane.Package/release.cmd | 20 ++++++------- Oqtane.Package/upgrade.ps1 | 2 +- .../Controllers/ModuleDefinitionController.cs | 6 ++-- Oqtane.Server/Controllers/ThemeController.cs | 4 +-- .../DbContextOptionsBuilderExtensions.cs | 4 ++- Oqtane.Server/Oqtane.Server.csproj | 28 +++++++++---------- .../[Owner].Module.[Module].Client.csproj | 12 ++++---- .../[Owner].Module.[Module].Package.csproj | 2 +- .../Package/[Owner].Module.[Module].nuspec | 12 ++++---- .../Templates/External/Package/debug.cmd | 12 ++++---- .../Templates/External/Package/debug.sh | 12 ++++---- .../[Owner].Module.[Module].Server.csproj | 10 +++---- .../[Owner].Module.[Module].Shared.csproj | 2 +- .../[Owner].Theme.[Theme].Client.csproj | 8 +++--- .../[Owner].Theme.[Theme].Package.csproj | 2 +- .../Package/[Owner].Theme.[Theme].nuspec | 4 +-- .../Templates/External/Package/debug.cmd | 4 +-- .../Templates/External/Package/debug.sh | 4 +-- Oqtane.Shared/Oqtane.Shared.csproj | 14 +++++----- Oqtane.Shared/Shared/Constants.cs | 4 +-- 32 files changed, 132 insertions(+), 130 deletions(-) diff --git a/Oqtane.Client/Installer/Installer.razor b/Oqtane.Client/Installer/Installer.razor index 94f9cc39..574b3730 100644 --- a/Oqtane.Client/Installer/Installer.razor +++ b/Oqtane.Client/Installer/Installer.razor @@ -15,7 +15,7 @@
-
@SharedLocalizer["Version"] @Constants.Version (.NET 8)
+
@SharedLocalizer["Version"] @Constants.Version (.NET 9)

diff --git a/Oqtane.Client/Oqtane.Client.csproj b/Oqtane.Client/Oqtane.Client.csproj index 72c6447c..63a3743c 100644 --- a/Oqtane.Client/Oqtane.Client.csproj +++ b/Oqtane.Client/Oqtane.Client.csproj @@ -1,10 +1,10 @@ - net8.0 + net9.0 Exe Debug;Release - 5.2.4 + 6.0.0 Oqtane Shaun Walker .NET Foundation @@ -12,7 +12,7 @@ .NET Foundation https://www.oqtane.org https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE - https://github.com/oqtane/oqtane.framework/releases/tag/v5.2.4 + https://github.com/oqtane/oqtane.framework/releases/tag/v6.0.0 https://github.com/oqtane/oqtane.framework Git Oqtane @@ -22,10 +22,10 @@ - - - - + + + + diff --git a/Oqtane.Database.MySQL/Oqtane.Database.MySQL.csproj b/Oqtane.Database.MySQL/Oqtane.Database.MySQL.csproj index d9911acd..cce8ad12 100644 --- a/Oqtane.Database.MySQL/Oqtane.Database.MySQL.csproj +++ b/Oqtane.Database.MySQL/Oqtane.Database.MySQL.csproj @@ -1,8 +1,8 @@ - net8.0 - 5.2.4 + net9.0 + 6.0.0 Oqtane Shaun Walker .NET Foundation @@ -10,7 +10,7 @@ .NET Foundation https://www.oqtane.org https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE - https://github.com/oqtane/oqtane.framework/releases/tag/v5.2.4 + https://github.com/oqtane/oqtane.framework/releases/tag/v6.0.0 https://github.com/oqtane/oqtane.framework Git true @@ -33,7 +33,7 @@ - + @@ -42,7 +42,7 @@ - + diff --git a/Oqtane.Database.PostgreSQL/Oqtane.Database.PostgreSQL.csproj b/Oqtane.Database.PostgreSQL/Oqtane.Database.PostgreSQL.csproj index 111a1251..79ed9b5c 100644 --- a/Oqtane.Database.PostgreSQL/Oqtane.Database.PostgreSQL.csproj +++ b/Oqtane.Database.PostgreSQL/Oqtane.Database.PostgreSQL.csproj @@ -1,8 +1,8 @@ - net8.0 - 5.2.4 + net9.0 + 6.0.0 Oqtane Shaun Walker .NET Foundation @@ -10,7 +10,7 @@ .NET Foundation https://www.oqtane.org https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE - https://github.com/oqtane/oqtane.framework/releases/tag/v5.2.4 + https://github.com/oqtane/oqtane.framework/releases/tag/v6.0.0 https://github.com/oqtane/oqtane.framework Git true @@ -34,8 +34,8 @@ - - + + @@ -43,7 +43,7 @@ - + diff --git a/Oqtane.Database.SqlServer/Oqtane.Database.SqlServer.csproj b/Oqtane.Database.SqlServer/Oqtane.Database.SqlServer.csproj index 48f7282f..69c82da2 100644 --- a/Oqtane.Database.SqlServer/Oqtane.Database.SqlServer.csproj +++ b/Oqtane.Database.SqlServer/Oqtane.Database.SqlServer.csproj @@ -1,8 +1,8 @@ - net8.0 - 5.2.4 + net9.0 + 6.0.0 Oqtane Shaun Walker .NET Foundation @@ -10,7 +10,7 @@ .NET Foundation https://www.oqtane.org https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE - https://github.com/oqtane/oqtane.framework/releases/tag/v5.2.4 + https://github.com/oqtane/oqtane.framework/releases/tag/v6.0.0 https://github.com/oqtane/oqtane.framework Git true @@ -33,7 +33,7 @@ - + @@ -41,7 +41,7 @@ - + diff --git a/Oqtane.Database.Sqlite/Oqtane.Database.Sqlite.csproj b/Oqtane.Database.Sqlite/Oqtane.Database.Sqlite.csproj index 1fa10f5b..6ff145b1 100644 --- a/Oqtane.Database.Sqlite/Oqtane.Database.Sqlite.csproj +++ b/Oqtane.Database.Sqlite/Oqtane.Database.Sqlite.csproj @@ -1,8 +1,8 @@ - net8.0 - 5.2.4 + net9.0 + 6.0.0 Oqtane Shaun Walker .NET Foundation @@ -10,7 +10,7 @@ .NET Foundation https://www.oqtane.org https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE - https://github.com/oqtane/oqtane.framework/releases/tag/v5.2.4 + https://github.com/oqtane/oqtane.framework/releases/tag/v6.0.0 https://github.com/oqtane/oqtane.framework Git true @@ -33,7 +33,7 @@ - + @@ -41,7 +41,7 @@ - + diff --git a/Oqtane.Package/Oqtane.Client.nuspec b/Oqtane.Package/Oqtane.Client.nuspec index 79a8088a..a01cd05d 100644 --- a/Oqtane.Package/Oqtane.Client.nuspec +++ b/Oqtane.Package/Oqtane.Client.nuspec @@ -2,7 +2,7 @@ Oqtane.Client - 5.2.4 + 6.0.0 Shaun Walker .NET Foundation Oqtane Framework @@ -12,14 +12,14 @@ false MIT https://github.com/oqtane/oqtane.framework - https://github.com/oqtane/oqtane.framework/releases/tag/v5.2.4 + https://github.com/oqtane/oqtane.framework/releases/tag/v6.0.0 readme.md icon.png oqtane - - + + diff --git a/Oqtane.Package/Oqtane.Framework.nuspec b/Oqtane.Package/Oqtane.Framework.nuspec index 5ddceeef..80b1baaa 100644 --- a/Oqtane.Package/Oqtane.Framework.nuspec +++ b/Oqtane.Package/Oqtane.Framework.nuspec @@ -2,7 +2,7 @@ Oqtane.Framework - 5.2.4 + 6.0.0 Shaun Walker .NET Foundation Oqtane Framework @@ -11,8 +11,8 @@ .NET Foundation false MIT - https://github.com/oqtane/oqtane.framework/releases/download/v5.2.4/Oqtane.Framework.5.2.4.Upgrade.zip - https://github.com/oqtane/oqtane.framework/releases/tag/v5.2.4 + https://github.com/oqtane/oqtane.framework/releases/download/v6.0.0/Oqtane.Framework.6.0.0.Upgrade.zip + https://github.com/oqtane/oqtane.framework/releases/tag/v6.0.0 readme.md icon.png oqtane framework diff --git a/Oqtane.Package/Oqtane.Server.nuspec b/Oqtane.Package/Oqtane.Server.nuspec index d43e9a3d..1be6a86d 100644 --- a/Oqtane.Package/Oqtane.Server.nuspec +++ b/Oqtane.Package/Oqtane.Server.nuspec @@ -2,7 +2,7 @@ Oqtane.Server - 5.2.4 + 6.0.0 Shaun Walker .NET Foundation Oqtane Framework @@ -12,14 +12,14 @@ false MIT https://github.com/oqtane/oqtane.framework - https://github.com/oqtane/oqtane.framework/releases/tag/v5.2.4 + https://github.com/oqtane/oqtane.framework/releases/tag/v6.0.0 readme.md icon.png oqtane - - + + diff --git a/Oqtane.Package/Oqtane.Shared.nuspec b/Oqtane.Package/Oqtane.Shared.nuspec index b9f466f8..9186c018 100644 --- a/Oqtane.Package/Oqtane.Shared.nuspec +++ b/Oqtane.Package/Oqtane.Shared.nuspec @@ -2,7 +2,7 @@ Oqtane.Shared - 5.2.4 + 6.0.0 Shaun Walker .NET Foundation Oqtane Framework @@ -12,14 +12,14 @@ false MIT https://github.com/oqtane/oqtane.framework - https://github.com/oqtane/oqtane.framework/releases/tag/v5.2.4 + https://github.com/oqtane/oqtane.framework/releases/tag/v6.0.0 readme.md icon.png oqtane - - + + diff --git a/Oqtane.Package/Oqtane.Updater.nuspec b/Oqtane.Package/Oqtane.Updater.nuspec index 8e3cc368..6a7911f8 100644 --- a/Oqtane.Package/Oqtane.Updater.nuspec +++ b/Oqtane.Package/Oqtane.Updater.nuspec @@ -2,7 +2,7 @@ Oqtane.Updater - 5.2.4 + 6.0.0 Shaun Walker .NET Foundation Oqtane Framework @@ -12,13 +12,13 @@ false MIT https://github.com/oqtane/oqtane.framework - https://github.com/oqtane/oqtane.framework/releases/tag/v5.2.4 + https://github.com/oqtane/oqtane.framework/releases/tag/v6.0.0 readme.md icon.png oqtane - + diff --git a/Oqtane.Package/install.ps1 b/Oqtane.Package/install.ps1 index 23cd8498..9f4ef87b 100644 --- a/Oqtane.Package/install.ps1 +++ b/Oqtane.Package/install.ps1 @@ -1 +1 @@ -Compress-Archive -Path "..\Oqtane.Server\bin\Release\net8.0\publish\*" -DestinationPath "Oqtane.Framework.5.2.4.Install.zip" -Force +Compress-Archive -Path "..\Oqtane.Server\bin\Release\net9.0\publish\*" -DestinationPath "Oqtane.Framework.6.0.0.Install.zip" -Force diff --git a/Oqtane.Package/release.cmd b/Oqtane.Package/release.cmd index 0b11fe27..2c9fde54 100644 --- a/Oqtane.Package/release.cmd +++ b/Oqtane.Package/release.cmd @@ -6,14 +6,14 @@ nuget.exe pack Oqtane.Client.nuspec nuget.exe pack Oqtane.Server.nuspec nuget.exe pack Oqtane.Shared.nuspec nuget.exe pack Oqtane.Framework.nuspec -del /F/Q/S "..\Oqtane.Server\bin\Release\net8.0\publish" > NUL -rmdir /Q/S "..\Oqtane.Server\bin\Release\net8.0\publish" +del /F/Q/S "..\Oqtane.Server\bin\Release\net9.0\publish" > NUL +rmdir /Q/S "..\Oqtane.Server\bin\Release\net9.0\publish" dotnet publish ..\Oqtane.Server\Oqtane.Server.csproj /p:Configuration=Release -del /F/Q/S "..\Oqtane.Server\bin\Release\net8.0\publish\wwwroot\Content" > NUL -rmdir /Q/S "..\Oqtane.Server\bin\Release\net8.0\publish\wwwroot\Content" +del /F/Q/S "..\Oqtane.Server\bin\Release\net9.0\publish\wwwroot\Content" > NUL +rmdir /Q/S "..\Oqtane.Server\bin\Release\net9.0\publish\wwwroot\Content" setlocal ENABLEDELAYEDEXPANSION set retain=Oqtane.Modules.Admin.Login,Oqtane.Modules.HtmlText -for /D %%i in ("..\Oqtane.Server\bin\Release\net8.0\publish\wwwroot\Modules\*") do ( +for /D %%i in ("..\Oqtane.Server\bin\Release\net9.0\publish\wwwroot\Modules\*") do ( set /A found=0 for %%j in (%retain%) do ( if "%%~nxi" == "%%j" set /A found=1 @@ -21,18 +21,18 @@ if "%%~nxi" == "%%j" set /A found=1 if not !found! == 1 rmdir /Q/S "%%i" ) set retain=Oqtane.Themes.BlazorTheme,Oqtane.Themes.OqtaneTheme -for /D %%i in ("..\Oqtane.Server\bin\Release\net8.0\publish\wwwroot\Themes\*") do ( +for /D %%i in ("..\Oqtane.Server\bin\Release\net9.0\publish\wwwroot\Themes\*") do ( set /A found=0 for %%j in (%retain%) do ( if "%%~nxi" == "%%j" set /A found=1 ) if not !found! == 1 rmdir /Q/S "%%i" ) -del "..\Oqtane.Server\bin\Release\net8.0\publish\appsettings.json" -ren "..\Oqtane.Server\bin\Release\net8.0\publish\appsettings.release.json" "appsettings.json" +del "..\Oqtane.Server\bin\Release\net9.0\publish\appsettings.json" +ren "..\Oqtane.Server\bin\Release\net9.0\publish\appsettings.release.json" "appsettings.json" C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe ".\install.ps1" -del "..\Oqtane.Server\bin\Release\net8.0\publish\appsettings.json" -del "..\Oqtane.Server\bin\Release\net8.0\publish\web.config" +del "..\Oqtane.Server\bin\Release\net9.0\publish\appsettings.json" +del "..\Oqtane.Server\bin\Release\net9.0\publish\web.config" C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe ".\upgrade.ps1" dotnet clean -c Release ..\Oqtane.Updater.sln dotnet build -c Release ..\Oqtane.Updater.sln diff --git a/Oqtane.Package/upgrade.ps1 b/Oqtane.Package/upgrade.ps1 index 19cc36ec..7ece0bea 100644 --- a/Oqtane.Package/upgrade.ps1 +++ b/Oqtane.Package/upgrade.ps1 @@ -1 +1 @@ -Compress-Archive -Path "..\Oqtane.Server\bin\Release\net8.0\publish\*" -DestinationPath "Oqtane.Framework.5.2.4.Upgrade.zip" -Force +Compress-Archive -Path "..\Oqtane.Server\bin\Release\net9.0\publish\*" -DestinationPath "Oqtane.Framework.6.0.0.Upgrade.zip" -Force diff --git a/Oqtane.Server/Controllers/ModuleDefinitionController.cs b/Oqtane.Server/Controllers/ModuleDefinitionController.cs index a637be69..601d5ce8 100644 --- a/Oqtane.Server/Controllers/ModuleDefinitionController.cs +++ b/Oqtane.Server/Controllers/ModuleDefinitionController.cs @@ -351,9 +351,9 @@ namespace Oqtane.Controllers return new Dictionary() { { "FrameworkVersion", Constants.Version }, - { "ClientReference", $"..\\..\\{rootFolder}\\Oqtane.Server\\bin\\Debug\\net8.0\\Oqtane.Client.dll" }, - { "ServerReference", $"..\\..\\{rootFolder}\\Oqtane.Server\\bin\\Debug\\net8.0\\Oqtane.Server.dll" }, - { "SharedReference", $"..\\..\\{rootFolder}\\Oqtane.Server\\bin\\Debug\\net8.0\\Oqtane.Shared.dll" }, + { "ClientReference", $"..\\..\\{rootFolder}\\Oqtane.Server\\bin\\Debug\\net9.0\\Oqtane.Client.dll" }, + { "ServerReference", $"..\\..\\{rootFolder}\\Oqtane.Server\\bin\\Debug\\net9.0\\Oqtane.Server.dll" }, + { "SharedReference", $"..\\..\\{rootFolder}\\Oqtane.Server\\bin\\Debug\\net9.0\\Oqtane.Shared.dll" }, }; }); } diff --git a/Oqtane.Server/Controllers/ThemeController.cs b/Oqtane.Server/Controllers/ThemeController.cs index 1eeee244..f42fc01b 100644 --- a/Oqtane.Server/Controllers/ThemeController.cs +++ b/Oqtane.Server/Controllers/ThemeController.cs @@ -267,8 +267,8 @@ namespace Oqtane.Controllers return new Dictionary() { { "FrameworkVersion", Constants.Version }, - { "ClientReference", $"..\\..\\{rootFolder}\\Oqtane.Server\\bin\\Debug\\net8.0\\Oqtane.Client.dll" }, - { "SharedReference", $"..\\..\\{rootFolder}\\Oqtane.Server\\bin\\Debug\\net8.0\\Oqtane.Shared.dll" }, + { "ClientReference", $"..\\..\\{rootFolder}\\Oqtane.Server\\bin\\Debug\\net9.0\\Oqtane.Client.dll" }, + { "SharedReference", $"..\\..\\{rootFolder}\\Oqtane.Server\\bin\\Debug\\net9.0\\Oqtane.Shared.dll" }, }; }); } diff --git a/Oqtane.Server/Extensions/DbContextOptionsBuilderExtensions.cs b/Oqtane.Server/Extensions/DbContextOptionsBuilderExtensions.cs index a35ecf77..2134708d 100644 --- a/Oqtane.Server/Extensions/DbContextOptionsBuilderExtensions.cs +++ b/Oqtane.Server/Extensions/DbContextOptionsBuilderExtensions.cs @@ -1,5 +1,6 @@ using System.Diagnostics.CodeAnalysis; using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Diagnostics; using Oqtane.Databases.Interfaces; // ReSharper disable ConvertToUsingDeclaration @@ -9,7 +10,8 @@ namespace Oqtane.Extensions { public static DbContextOptionsBuilder UseOqtaneDatabase([NotNull] this DbContextOptionsBuilder optionsBuilder, IDatabase database, string connectionString) { - database.UseDatabase(optionsBuilder, connectionString); + database.UseDatabase(optionsBuilder, connectionString) + .ConfigureWarnings(warnings => warnings.Log(RelationalEventId.PendingModelChangesWarning)); return optionsBuilder; } diff --git a/Oqtane.Server/Oqtane.Server.csproj b/Oqtane.Server/Oqtane.Server.csproj index d5c51ea8..a78c8424 100644 --- a/Oqtane.Server/Oqtane.Server.csproj +++ b/Oqtane.Server/Oqtane.Server.csproj @@ -1,9 +1,9 @@ - net8.0 + net9.0 Debug;Release - 5.2.4 + 6.0.0 Oqtane Shaun Walker .NET Foundation @@ -11,7 +11,7 @@ .NET Foundation https://www.oqtane.org https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE - https://github.com/oqtane/oqtane.framework/releases/tag/v5.2.4 + https://github.com/oqtane/oqtane.framework/releases/tag/v6.0.0 https://github.com/oqtane/oqtane.framework Git Oqtane @@ -33,21 +33,21 @@ - - - - - - + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - + + + + + + diff --git a/Oqtane.Server/wwwroot/Modules/Templates/External/Client/[Owner].Module.[Module].Client.csproj b/Oqtane.Server/wwwroot/Modules/Templates/External/Client/[Owner].Module.[Module].Client.csproj index 21ef0312..0c3de498 100644 --- a/Oqtane.Server/wwwroot/Modules/Templates/External/Client/[Owner].Module.[Module].Client.csproj +++ b/Oqtane.Server/wwwroot/Modules/Templates/External/Client/[Owner].Module.[Module].Client.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 1.0.0 [Owner] [Owner] @@ -13,12 +13,12 @@ - - - - - + + + + + diff --git a/Oqtane.Server/wwwroot/Modules/Templates/External/Package/[Owner].Module.[Module].Package.csproj b/Oqtane.Server/wwwroot/Modules/Templates/External/Package/[Owner].Module.[Module].Package.csproj index e7843bff..b255b8bb 100644 --- a/Oqtane.Server/wwwroot/Modules/Templates/External/Package/[Owner].Module.[Module].Package.csproj +++ b/Oqtane.Server/wwwroot/Modules/Templates/External/Package/[Owner].Module.[Module].Package.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 false false diff --git a/Oqtane.Server/wwwroot/Modules/Templates/External/Package/[Owner].Module.[Module].nuspec b/Oqtane.Server/wwwroot/Modules/Templates/External/Package/[Owner].Module.[Module].nuspec index a09ebb95..4098fedf 100644 --- a/Oqtane.Server/wwwroot/Modules/Templates/External/Package/[Owner].Module.[Module].nuspec +++ b/Oqtane.Server/wwwroot/Modules/Templates/External/Package/[Owner].Module.[Module].nuspec @@ -20,12 +20,12 @@ - - - - - - + + + + + + diff --git a/Oqtane.Server/wwwroot/Modules/Templates/External/Package/debug.cmd b/Oqtane.Server/wwwroot/Modules/Templates/External/Package/debug.cmd index e59e74cd..87d0dcf3 100644 --- a/Oqtane.Server/wwwroot/Modules/Templates/External/Package/debug.cmd +++ b/Oqtane.Server/wwwroot/Modules/Templates/External/Package/debug.cmd @@ -1,7 +1,7 @@ -XCOPY "..\Client\bin\Debug\net8.0\[Owner].Module.[Module].Client.Oqtane.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net8.0\" /Y -XCOPY "..\Client\bin\Debug\net8.0\[Owner].Module.[Module].Client.Oqtane.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net8.0\" /Y -XCOPY "..\Server\bin\Debug\net8.0\[Owner].Module.[Module].Server.Oqtane.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net8.0\" /Y -XCOPY "..\Server\bin\Debug\net8.0\[Owner].Module.[Module].Server.Oqtane.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net8.0\" /Y -XCOPY "..\Shared\bin\Debug\net8.0\[Owner].Module.[Module].Shared.Oqtane.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net8.0\" /Y -XCOPY "..\Shared\bin\Debug\net8.0\[Owner].Module.[Module].Shared.Oqtane.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net8.0\" /Y +XCOPY "..\Client\bin\Debug\net9.0\[Owner].Module.[Module].Client.Oqtane.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net9.0\" /Y +XCOPY "..\Client\bin\Debug\net9.0\[Owner].Module.[Module].Client.Oqtane.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net9.0\" /Y +XCOPY "..\Server\bin\Debug\net9.0\[Owner].Module.[Module].Server.Oqtane.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net9.0\" /Y +XCOPY "..\Server\bin\Debug\net9.0\[Owner].Module.[Module].Server.Oqtane.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net9.0\" /Y +XCOPY "..\Shared\bin\Debug\net9.0\[Owner].Module.[Module].Shared.Oqtane.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net9.0\" /Y +XCOPY "..\Shared\bin\Debug\net9.0\[Owner].Module.[Module].Shared.Oqtane.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net9.0\" /Y XCOPY "..\Server\wwwroot\*" "..\..\[RootFolder]\Oqtane.Server\wwwroot\" /Y /S /I diff --git a/Oqtane.Server/wwwroot/Modules/Templates/External/Package/debug.sh b/Oqtane.Server/wwwroot/Modules/Templates/External/Package/debug.sh index 792ce75c..7a5cc808 100644 --- a/Oqtane.Server/wwwroot/Modules/Templates/External/Package/debug.sh +++ b/Oqtane.Server/wwwroot/Modules/Templates/External/Package/debug.sh @@ -1,7 +1,7 @@ -cp -f "../Client/bin/Debug/net8.0/[Owner].Module.[Module].Client.Oqtane.dll" "../../oqtane.framework/Oqtane.Server/bin/Debug/net8.0/" -cp -f "../Client/bin/Debug/net8.0/[Owner].Module.[Module].Client.Oqtane.pdb" "../../oqtane.framework/Oqtane.Server/bin/Debug/net8.0/" -cp -f "../Server/bin/Debug/net8.0/[Owner].Module.[Module].Server.Oqtane.dll" "../../oqtane.framework/Oqtane.Server/bin/Debug/net8.0/" -cp -f "../Server/bin/Debug/net8.0/[Owner].Module.[Module].Server.Oqtane.pdb" "../../oqtane.framework/Oqtane.Server/bin/Debug/net8.0/" -cp -f "../Shared/bin/Debug/net8.0/[Owner].Module.[Module].Shared.Oqtane.dll" "../../oqtane.framework/Oqtane.Server/bin/Debug/net8.0/" -cp -f "../Shared/bin/Debug/net8.0/[Owner].Module.[Module].Shared.Oqtane.pdb" "../../oqtane.framework/Oqtane.Server/bin/Debug/net8.0/" +cp -f "../Client/bin/Debug/net9.0/[Owner].Module.[Module].Client.Oqtane.dll" "../../oqtane.framework/Oqtane.Server/bin/Debug/net9.0/" +cp -f "../Client/bin/Debug/net9.0/[Owner].Module.[Module].Client.Oqtane.pdb" "../../oqtane.framework/Oqtane.Server/bin/Debug/net9.0/" +cp -f "../Server/bin/Debug/net9.0/[Owner].Module.[Module].Server.Oqtane.dll" "../../oqtane.framework/Oqtane.Server/bin/Debug/net9.0/" +cp -f "../Server/bin/Debug/net9.0/[Owner].Module.[Module].Server.Oqtane.pdb" "../../oqtane.framework/Oqtane.Server/bin/Debug/net9.0/" +cp -f "../Shared/bin/Debug/net9.0/[Owner].Module.[Module].Shared.Oqtane.dll" "../../oqtane.framework/Oqtane.Server/bin/Debug/net9.0/" +cp -f "../Shared/bin/Debug/net9.0/[Owner].Module.[Module].Shared.Oqtane.pdb" "../../oqtane.framework/Oqtane.Server/bin/Debug/net9.0/" cp -rf "../Server/wwwroot/"* "../../oqtane.framework/Oqtane.Server/wwwroot/" diff --git a/Oqtane.Server/wwwroot/Modules/Templates/External/Server/[Owner].Module.[Module].Server.csproj b/Oqtane.Server/wwwroot/Modules/Templates/External/Server/[Owner].Module.[Module].Server.csproj index 8a9cfe06..7f0a1262 100644 --- a/Oqtane.Server/wwwroot/Modules/Templates/External/Server/[Owner].Module.[Module].Server.csproj +++ b/Oqtane.Server/wwwroot/Modules/Templates/External/Server/[Owner].Module.[Module].Server.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 true 1.0.0 [Owner].Module.[Module] @@ -19,10 +19,10 @@ - - - - + + + + diff --git a/Oqtane.Server/wwwroot/Modules/Templates/External/Shared/[Owner].Module.[Module].Shared.csproj b/Oqtane.Server/wwwroot/Modules/Templates/External/Shared/[Owner].Module.[Module].Shared.csproj index a4cc724b..dd2e3d40 100644 --- a/Oqtane.Server/wwwroot/Modules/Templates/External/Shared/[Owner].Module.[Module].Shared.csproj +++ b/Oqtane.Server/wwwroot/Modules/Templates/External/Shared/[Owner].Module.[Module].Shared.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 1.0.0 [Owner].Module.[Module] [Owner] diff --git a/Oqtane.Server/wwwroot/Themes/Templates/External/Client/[Owner].Theme.[Theme].Client.csproj b/Oqtane.Server/wwwroot/Themes/Templates/External/Client/[Owner].Theme.[Theme].Client.csproj index 48056a8a..a25114e5 100644 --- a/Oqtane.Server/wwwroot/Themes/Templates/External/Client/[Owner].Theme.[Theme].Client.csproj +++ b/Oqtane.Server/wwwroot/Themes/Templates/External/Client/[Owner].Theme.[Theme].Client.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 1.0.0 [Owner] [Owner] @@ -13,9 +13,9 @@ - - - + + + diff --git a/Oqtane.Server/wwwroot/Themes/Templates/External/Package/[Owner].Theme.[Theme].Package.csproj b/Oqtane.Server/wwwroot/Themes/Templates/External/Package/[Owner].Theme.[Theme].Package.csproj index 0f6cc8ea..e77b1274 100644 --- a/Oqtane.Server/wwwroot/Themes/Templates/External/Package/[Owner].Theme.[Theme].Package.csproj +++ b/Oqtane.Server/wwwroot/Themes/Templates/External/Package/[Owner].Theme.[Theme].Package.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 false false diff --git a/Oqtane.Server/wwwroot/Themes/Templates/External/Package/[Owner].Theme.[Theme].nuspec b/Oqtane.Server/wwwroot/Themes/Templates/External/Package/[Owner].Theme.[Theme].nuspec index 584fc6a6..917b02c9 100644 --- a/Oqtane.Server/wwwroot/Themes/Templates/External/Package/[Owner].Theme.[Theme].nuspec +++ b/Oqtane.Server/wwwroot/Themes/Templates/External/Package/[Owner].Theme.[Theme].nuspec @@ -20,8 +20,8 @@ - - + + diff --git a/Oqtane.Server/wwwroot/Themes/Templates/External/Package/debug.cmd b/Oqtane.Server/wwwroot/Themes/Templates/External/Package/debug.cmd index 2ece53b9..31c7cf33 100644 --- a/Oqtane.Server/wwwroot/Themes/Templates/External/Package/debug.cmd +++ b/Oqtane.Server/wwwroot/Themes/Templates/External/Package/debug.cmd @@ -1,3 +1,3 @@ -XCOPY "..\Client\bin\Debug\net8.0\[Owner].Theme.[Theme].Client.Oqtane.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net8.0\" /Y -XCOPY "..\Client\bin\Debug\net8.0\[Owner].Theme.[Theme].Client.Oqtane.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net8.0\" /Y +XCOPY "..\Client\bin\Debug\net9.0\[Owner].Theme.[Theme].Client.Oqtane.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net9.0\" /Y +XCOPY "..\Client\bin\Debug\net9.0\[Owner].Theme.[Theme].Client.Oqtane.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net9.0\" /Y XCOPY "..\Client\wwwroot\*" "..\..\[RootFolder]\Oqtane.Server\wwwroot\" /Y /S /I diff --git a/Oqtane.Server/wwwroot/Themes/Templates/External/Package/debug.sh b/Oqtane.Server/wwwroot/Themes/Templates/External/Package/debug.sh index 52ec3384..4ac1ad54 100644 --- a/Oqtane.Server/wwwroot/Themes/Templates/External/Package/debug.sh +++ b/Oqtane.Server/wwwroot/Themes/Templates/External/Package/debug.sh @@ -1,3 +1,3 @@ -cp -f "../Client/bin/Debug/net8.0/[Owner].Theme.[Theme].Client.Oqtane.dll" "../../oqtane.framework/Oqtane.Server/bin/Debug/net8.0/" -cp -f "../Client/bin/Debug/net8.0/[Owner].Theme.[Theme].Client.Oqtane.pdb" "../../oqtane.framework/Oqtane.Server/bin/Debug/net8.0/" +cp -f "../Client/bin/Debug/net9.0/[Owner].Theme.[Theme].Client.Oqtane.dll" "../../oqtane.framework/Oqtane.Server/bin/Debug/net9.0/" +cp -f "../Client/bin/Debug/net9.0/[Owner].Theme.[Theme].Client.Oqtane.pdb" "../../oqtane.framework/Oqtane.Server/bin/Debug/net9.0/" cp -rf "../Server/wwwroot/"* "../../oqtane.framework/Oqtane.Server/wwwroot/" diff --git a/Oqtane.Shared/Oqtane.Shared.csproj b/Oqtane.Shared/Oqtane.Shared.csproj index ab34bf21..ff45903a 100644 --- a/Oqtane.Shared/Oqtane.Shared.csproj +++ b/Oqtane.Shared/Oqtane.Shared.csproj @@ -1,9 +1,9 @@ - net8.0 + net9.0 Debug;Release - 5.2.4 + 6.0.0 Oqtane Shaun Walker .NET Foundation @@ -11,7 +11,7 @@ .NET Foundation https://www.oqtane.org https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE - https://github.com/oqtane/oqtane.framework/releases/tag/v5.2.4 + https://github.com/oqtane/oqtane.framework/releases/tag/v6.0.0 https://github.com/oqtane/oqtane.framework Git Oqtane @@ -19,11 +19,11 @@ - - - + + + - + diff --git a/Oqtane.Shared/Shared/Constants.cs b/Oqtane.Shared/Shared/Constants.cs index 12edb80b..aa83db6c 100644 --- a/Oqtane.Shared/Shared/Constants.cs +++ b/Oqtane.Shared/Shared/Constants.cs @@ -4,8 +4,8 @@ namespace Oqtane.Shared { public class Constants { - public static readonly string Version = "5.2.4"; - public const string ReleaseVersions = "1.0.0,1.0.1,1.0.2,1.0.3,1.0.4,2.0.0,2.0.1,2.0.2,2.1.0,2.2.0,2.3.0,2.3.1,3.0.0,3.0.1,3.0.2,3.0.3,3.1.0,3.1.1,3.1.2,3.1.3,3.1.4,3.2.0,3.2.1,3.3.0,3.3.1,3.4.0,3.4.1,3.4.2,3.4.3,4.0.0,4.0.1,4.0.2,4.0.3,4.0.4,4.0.5,4.0.6,5.0.0,5.0.1,5.0.2,5.0.3,5.1.0,5.1.1,5.1.2,5.2.0,5.2.1,5.2.2,5.2.3,5.2.4"; + public static readonly string Version = "6.0.0"; + public const string ReleaseVersions = "1.0.0,1.0.1,1.0.2,1.0.3,1.0.4,2.0.0,2.0.1,2.0.2,2.1.0,2.2.0,2.3.0,2.3.1,3.0.0,3.0.1,3.0.2,3.0.3,3.1.0,3.1.1,3.1.2,3.1.3,3.1.4,3.2.0,3.2.1,3.3.0,3.3.1,3.4.0,3.4.1,3.4.2,3.4.3,4.0.0,4.0.1,4.0.2,4.0.3,4.0.4,4.0.5,4.0.6,5.0.0,5.0.1,5.0.2,5.0.3,5.1.0,5.1.1,5.1.2,5.2.0,5.2.1,5.2.2,5.2.3,5.2.4,6.0.0"; public const string PackageId = "Oqtane.Framework"; public const string ClientId = "Oqtane.Client"; public const string UpdaterPackageId = "Oqtane.Updater"; From 369bf7a235489783671efb20f73aa9aa3e5d2f63 Mon Sep 17 00:00:00 2001 From: Cody Date: Mon, 21 Oct 2024 12:20:24 -0700 Subject: [PATCH 05/38] Adds logic for `.modal` class ScrollTo function fixes #4762 --- Oqtane.Maui/wwwroot/js/interop.js | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/Oqtane.Maui/wwwroot/js/interop.js b/Oqtane.Maui/wwwroot/js/interop.js index ef6043f9..675cebca 100644 --- a/Oqtane.Maui/wwwroot/js/interop.js +++ b/Oqtane.Maui/wwwroot/js/interop.js @@ -417,11 +417,20 @@ Oqtane.Interop = { } }, scrollTo: function (top, left, behavior) { - window.scrollTo({ - top: top, - left: left, - behavior: behavior - }); + const modal = document.querySelector('.modal'); + if (modal) { + modal.scrollTo({ + top: top, + left: left, + behavior: behavior + }); + } else { + window.scrollTo({ + top: top, + left: left, + behavior: behavior + }); + } }, scrollToId: function (id) { var element = document.getElementById(id); From 4be2f4f2d9456b9ed24d34cf427b588f07cc9c24 Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Mon, 21 Oct 2024 15:21:29 -0400 Subject: [PATCH 06/38] Update README.md --- README.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a93ac330..d7bda849 100644 --- a/README.md +++ b/README.md @@ -83,12 +83,10 @@ Connect with other developers, get support, and share ideas by joining the Oqtan # Roadmap This project is open source, and therefore is a work in progress... - -Backlog (TBD) -- [ ] Azure Autoscale support (ie. web farm) -- [ ] Folder Providers -- [ ] Generative AI Integration +6.0.0 (Nov 13, 2024) +- [x] Migration to .NET 9 + [5.2.4](https://github.com/oqtane/oqtane.framework/releases/tag/v5.2.4) (Oct 17, 2024) - [x] Stabilization improvements From 8a9651dc50a07843e902ee1c591080c3d1d92773 Mon Sep 17 00:00:00 2001 From: Cody Date: Mon, 21 Oct 2024 12:22:01 -0700 Subject: [PATCH 07/38] Adds logic for .modal class ScrollTo function --- Oqtane.Server/wwwroot/js/interop.js | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/Oqtane.Server/wwwroot/js/interop.js b/Oqtane.Server/wwwroot/js/interop.js index ef6043f9..675cebca 100644 --- a/Oqtane.Server/wwwroot/js/interop.js +++ b/Oqtane.Server/wwwroot/js/interop.js @@ -417,11 +417,20 @@ Oqtane.Interop = { } }, scrollTo: function (top, left, behavior) { - window.scrollTo({ - top: top, - left: left, - behavior: behavior - }); + const modal = document.querySelector('.modal'); + if (modal) { + modal.scrollTo({ + top: top, + left: left, + behavior: behavior + }); + } else { + window.scrollTo({ + top: top, + left: left, + behavior: behavior + }); + } }, scrollToId: function (id) { var element = document.getElementById(id); From 42e5c6e1115d85aae396b2f3662c9854b9d408c3 Mon Sep 17 00:00:00 2001 From: sbwalker Date: Mon, 21 Oct 2024 15:25:14 -0400 Subject: [PATCH 08/38] update Updater to .NET 9 --- Oqtane.Updater/Oqtane.Updater.csproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Oqtane.Updater/Oqtane.Updater.csproj b/Oqtane.Updater/Oqtane.Updater.csproj index aab4be52..8f111c0b 100644 --- a/Oqtane.Updater/Oqtane.Updater.csproj +++ b/Oqtane.Updater/Oqtane.Updater.csproj @@ -1,9 +1,9 @@ - net8.0 + net9.0 Exe - 5.2.4 + 6.0.0 Oqtane Shaun Walker .NET Foundation @@ -11,7 +11,7 @@ .NET Foundation https://www.oqtane.org https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE - https://github.com/oqtane/oqtane.framework/releases/tag/v5.2.4 + https://github.com/oqtane/oqtane.framework/releases/tag/v6.0.0 https://github.com/oqtane/oqtane.framework Git Oqtane From 1516d5af10c6fbb33f0cfc20be43c82346c686e5 Mon Sep 17 00:00:00 2001 From: sbwalker Date: Mon, 21 Oct 2024 15:34:22 -0400 Subject: [PATCH 09/38] update MAUI project to .NET 9 RC2 --- Oqtane.Maui/Oqtane.Maui.csproj | 46 +++++++++++++++++----------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/Oqtane.Maui/Oqtane.Maui.csproj b/Oqtane.Maui/Oqtane.Maui.csproj index 9697adab..5f05face 100644 --- a/Oqtane.Maui/Oqtane.Maui.csproj +++ b/Oqtane.Maui/Oqtane.Maui.csproj @@ -1,12 +1,12 @@ - $(TargetFrameworks);net8.0-windows10.0.19041.0 + $(TargetFrameworks);net9.0-windows10.0.19041.0 - - + + Exe - 5.2.4 + 6.0.0 Oqtane Shaun Walker .NET Foundation @@ -14,7 +14,7 @@ .NET Foundation https://www.oqtane.org https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE - https://github.com/oqtane/oqtane.framework/releases/tag/v5.2.4 + https://github.com/oqtane/oqtane.framework/releases/tag/v6.0.0 https://github.com/oqtane/oqtane.framework Git Oqtane.Maui @@ -31,16 +31,16 @@ 0E29FC31-1B83-48ED-B6E0-9F3C67B775D4 - 5.2.4 + 6.0.0 1 - 14.2 - 14.0 - 24.0 - 10.0.17763.0 - 10.0.17763.0 - 6.5 - + 15.0 + 15.0 + 24.0 + 10.0.17763.0 + 10.0.17763.0 + 6.5 + @@ -65,23 +65,23 @@ - - + + - - - - - - + + + + + + - ..\Oqtane.Server\bin\Debug\net8.0\Oqtane.Client.dll + ..\Oqtane.Server\bin\Debug\net9.0\Oqtane.Client.dll - ..\Oqtane.Server\bin\Debug\net8.0\Oqtane.Shared.dll + ..\Oqtane.Server\bin\Debug\net9.0\Oqtane.Shared.dll From a9ea41a4887513cd06d0ee4c4792202e977027d4 Mon Sep 17 00:00:00 2001 From: sbwalker Date: Mon, 21 Oct 2024 15:41:57 -0400 Subject: [PATCH 10/38] resolve compiler warning in .NET MAUI --- Oqtane.Maui/App.xaml.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Oqtane.Maui/App.xaml.cs b/Oqtane.Maui/App.xaml.cs index 0d60ea85..4a344371 100644 --- a/Oqtane.Maui/App.xaml.cs +++ b/Oqtane.Maui/App.xaml.cs @@ -5,7 +5,10 @@ public partial class App : Application public App() { InitializeComponent(); - - MainPage = new MainPage(); } + + protected override Window CreateWindow(IActivationState? activationState) + { + return new Window(new MainPage()); + } } From ce51262197fa67c1e57880c22c209fdf6f5df033 Mon Sep 17 00:00:00 2001 From: Ben Date: Thu, 24 Oct 2024 20:04:18 +0800 Subject: [PATCH 11/38] update the code to use simple validation. --- Oqtane.Client/Installer/Installer.razor | 2 +- .../Resources/Installer/Installer.resx | 5 +- Oqtane.Server/Managers/InstallUserManager.cs | 41 ------------ Oqtane.Server/Managers/UserManager.cs | 63 +++---------------- 4 files changed, 14 insertions(+), 97 deletions(-) delete mode 100644 Oqtane.Server/Managers/InstallUserManager.cs diff --git a/Oqtane.Client/Installer/Installer.razor b/Oqtane.Client/Installer/Installer.razor index 20d4742e..9fb1aa55 100644 --- a/Oqtane.Client/Installer/Installer.razor +++ b/Oqtane.Client/Installer/Installer.razor @@ -279,7 +279,7 @@ } else { - _message = string.Join("
", result.Errors.Select(i => i.Value)); + _message = string.Join("
", result.Errors.Select(i => !string.IsNullOrEmpty(i.Value) ? i.Value : Localizer[i.Key])); } } else diff --git a/Oqtane.Client/Resources/Installer/Installer.resx b/Oqtane.Client/Resources/Installer/Installer.resx index 23e0f7d7..f6b4a7d6 100644 --- a/Oqtane.Client/Resources/Installer/Installer.resx +++ b/Oqtane.Client/Resources/Installer/Installer.resx @@ -136,7 +136,7 @@ Please Enter All Required Fields. Ensure Passwords Match And Email Address Provided Is Valid. - The Password Provided Does Not Meet The Complexity Policy. Passwords Must Be At Least 6 Characters In Length And Contain Uppercase, Lowercase, Numeric, And Punctuation Characters. + The Password Provided Does Not Meet The Complexity Policy For Below Reasons: Please Register Me For Major Product Updates And Security Bulletins @@ -183,4 +183,7 @@ Select a site template + + The Username Provided Does Not Meet The System Requirement, It Can Only Contains Letters Or Digits. + \ No newline at end of file diff --git a/Oqtane.Server/Managers/InstallUserManager.cs b/Oqtane.Server/Managers/InstallUserManager.cs deleted file mode 100644 index 909b36e7..00000000 --- a/Oqtane.Server/Managers/InstallUserManager.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Identity; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; - -namespace Oqtane.Managers -{ - /// - /// This class is only used for user validation during installation process. - /// - /// - internal class InstallUserManager : UserManager - { - public InstallUserManager(IUserStore store, IOptions optionsAccessor, IPasswordHasher passwordHasher, IEnumerable> userValidators, IEnumerable> passwordValidators, ILookupNormalizer keyNormalizer, IdentityErrorDescriber errors, IServiceProvider services, ILogger> logger) : base(store, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors, services, logger) - { - } - - public override async Task FindByNameAsync(string userName) - { - await Task.CompletedTask; - - return null; - } - - public override async Task FindByEmailAsync(string email) - { - await Task.CompletedTask; - - return null; - } - - public override async Task GetUserIdAsync(IdentityUser user) - { - await Task.CompletedTask; - - return null; - } - } -} diff --git a/Oqtane.Server/Managers/UserManager.cs b/Oqtane.Server/Managers/UserManager.cs index 76e0c05d..821e8cd8 100644 --- a/Oqtane.Server/Managers/UserManager.cs +++ b/Oqtane.Server/Managers/UserManager.cs @@ -33,41 +33,8 @@ namespace Oqtane.Managers private readonly ILogManager _logger; private readonly IMemoryCache _cache; private readonly IStringLocalizer _localizer; - private readonly IUserStore _identityStore; - private readonly Microsoft.Extensions.Options.IOptions _identityOptionsAccessor; - private readonly IPasswordHasher _passwordHasher; - private readonly IEnumerable> _userValidators; - private readonly IEnumerable> _passwordValidators; - private readonly ILookupNormalizer _identityKeyNormalizer; - private readonly IdentityErrorDescriber _identityErrors; - private readonly IServiceProvider _identityServices; - private readonly Microsoft.Extensions.Logging.ILogger> _identityLogger; - public UserManager( - IUserRepository users, - IRoleRepository roles, - IUserRoleRepository userRoles, - UserManager identityUserManager, - SignInManager identitySignInManager, - ITenantManager tenantManager, - INotificationRepository notifications, - IFolderRepository folders, - IProfileRepository profiles, - ISettingRepository settings, - ISiteRepository sites, - ISyncManager syncManager, - ILogManager logger, - IMemoryCache cache, - IStringLocalizer localizer, - IUserStore store, - Microsoft.Extensions.Options.IOptions optionsAccessor, - IPasswordHasher passwordHasher, - IEnumerable> userValidators, - IEnumerable> passwordValidators, - ILookupNormalizer keyNormalizer, - IdentityErrorDescriber errors, - IServiceProvider services, - Microsoft.Extensions.Logging.ILogger> identityLogger) + public UserManager(IUserRepository users, IRoleRepository roles, IUserRoleRepository userRoles, UserManager identityUserManager, SignInManager identitySignInManager, ITenantManager tenantManager, INotificationRepository notifications, IFolderRepository folders, IProfileRepository profiles, ISettingRepository settings, ISiteRepository sites, ISyncManager syncManager, ILogManager logger, IMemoryCache cache, IStringLocalizer localizer) { _users = users; _roles = roles; @@ -84,15 +51,6 @@ namespace Oqtane.Managers _logger = logger; _cache = cache; _localizer = localizer; - _identityStore = store; - _identityOptionsAccessor = optionsAccessor; - _passwordHasher = passwordHasher; - _userValidators = userValidators; - _passwordValidators = passwordValidators; - _identityKeyNormalizer = keyNormalizer; - _identityErrors = errors; - _identityServices = services; - _identityLogger = identityLogger; } public User GetUser(int userid, int siteid) @@ -585,25 +543,22 @@ namespace Oqtane.Managers public async Task ValidateUser(string username, string email, string password) { var validateResult = new UserValidateResult { Succeeded = true }; - var installUserManager = new InstallUserManager(_identityStore, _identityOptionsAccessor, _passwordHasher, _userValidators, _passwordValidators, _identityKeyNormalizer, _identityErrors, _identityServices, _identityLogger); - var user = new IdentityUser { UserName = username, Email = email, EmailConfirmed = true }; - var userValidator = new UserValidator(); - var userResult = await userValidator.ValidateAsync(installUserManager, user); - if (!userResult.Succeeded) + //validate username + var allowedChars = _identityUserManager.Options.User.AllowedUserNameCharacters; + if (string.IsNullOrWhiteSpace(username) || (!string.IsNullOrEmpty(allowedChars) && username.Any(c => !allowedChars.Contains(c)))) { validateResult.Succeeded = false; - if(userResult.Errors != null) - { - validateResult.Errors = userResult.Errors?.ToDictionary(i => i.Code, i => i.Description); - } + validateResult.Errors.Add("Message.Username.Invalid", string.Empty); } + //validate password var passwordValidator = new PasswordValidator(); - var passwordResult = await passwordValidator.ValidateAsync(installUserManager, null, password); - if (!passwordResult.Succeeded && !validateResult.Errors.ContainsKey("InvalidPassword")) + var passwordResult = await passwordValidator.ValidateAsync(_identityUserManager, null, password); + if (!passwordResult.Succeeded) { validateResult.Succeeded = false; + validateResult.Errors.Add("Message.Password.Invalid", string.Empty); if (passwordResult.Errors != null) { foreach (var error in passwordResult.Errors) From 3565185808125f176002a1a4f89926b54c1db6dd Mon Sep 17 00:00:00 2001 From: Ben Date: Thu, 24 Oct 2024 20:13:43 +0800 Subject: [PATCH 12/38] update the error message. --- Oqtane.Client/Resources/Installer/Installer.resx | 2 +- Oqtane.Server/Managers/UserManager.cs | 7 ------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/Oqtane.Client/Resources/Installer/Installer.resx b/Oqtane.Client/Resources/Installer/Installer.resx index f6b4a7d6..a06752d9 100644 --- a/Oqtane.Client/Resources/Installer/Installer.resx +++ b/Oqtane.Client/Resources/Installer/Installer.resx @@ -136,7 +136,7 @@ Please Enter All Required Fields. Ensure Passwords Match And Email Address Provided Is Valid. - The Password Provided Does Not Meet The Complexity Policy For Below Reasons: + The Password Provided Does Not Meet The Complexity Policy. Passwords Must Be At Least 6 Characters In Length And Contain Uppercase, Lowercase, Numeric, And Punctuation Characters. Please Register Me For Major Product Updates And Security Bulletins diff --git a/Oqtane.Server/Managers/UserManager.cs b/Oqtane.Server/Managers/UserManager.cs index 821e8cd8..03bff1bb 100644 --- a/Oqtane.Server/Managers/UserManager.cs +++ b/Oqtane.Server/Managers/UserManager.cs @@ -559,13 +559,6 @@ namespace Oqtane.Managers { validateResult.Succeeded = false; validateResult.Errors.Add("Message.Password.Invalid", string.Empty); - if (passwordResult.Errors != null) - { - foreach (var error in passwordResult.Errors) - { - validateResult.Errors.Add(error.Code, error.Description); - } - } } return validateResult; From a967332f892c601cb09827a4b5c1583373213a63 Mon Sep 17 00:00:00 2001 From: sbwalker Date: Thu, 24 Oct 2024 12:24:46 -0400 Subject: [PATCH 13/38] remove Microsoft.AspNetCore.Localization --- .../Modules/Admin/Languages/Add.razor | 1 - .../Modules/Admin/Languages/Edit.razor | 1 - .../Admin/ModuleDefinitions/Edit.razor | 1 - Oqtane.Client/Oqtane.Client.csproj | 2 +- Oqtane.Client/Program.cs | 5 +- .../Controls/Theme/LanguageSwitcher.razor | 3 +- Oqtane.Server/Components/App.razor | 6 +- Oqtane.Shared/Models/RequestCulture.cs | 67 ++++++++++++++ .../Shared/CookieRequestCultureProvider.cs | 89 +++++++++++++++++++ 9 files changed, 163 insertions(+), 12 deletions(-) create mode 100644 Oqtane.Shared/Models/RequestCulture.cs create mode 100644 Oqtane.Shared/Shared/CookieRequestCultureProvider.cs diff --git a/Oqtane.Client/Modules/Admin/Languages/Add.razor b/Oqtane.Client/Modules/Admin/Languages/Add.razor index 52a958c2..fedc045b 100644 --- a/Oqtane.Client/Modules/Admin/Languages/Add.razor +++ b/Oqtane.Client/Modules/Admin/Languages/Add.razor @@ -1,7 +1,6 @@ @namespace Oqtane.Modules.Admin.Languages @inherits ModuleBase @using System.Globalization -@using Microsoft.AspNetCore.Localization @inject NavigationManager NavigationManager @inject ILocalizationService LocalizationService @inject ILanguageService LanguageService diff --git a/Oqtane.Client/Modules/Admin/Languages/Edit.razor b/Oqtane.Client/Modules/Admin/Languages/Edit.razor index 7aa074c7..3a4060ac 100644 --- a/Oqtane.Client/Modules/Admin/Languages/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Languages/Edit.razor @@ -1,7 +1,6 @@ @namespace Oqtane.Modules.Admin.Languages @inherits ModuleBase @using System.Globalization -@using Microsoft.AspNetCore.Localization @inject NavigationManager NavigationManager @inject ILocalizationService LocalizationService @inject ILanguageService LanguageService diff --git a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Edit.razor b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Edit.razor index ffa2f1e3..4693891e 100644 --- a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Edit.razor +++ b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Edit.razor @@ -1,7 +1,6 @@ @namespace Oqtane.Modules.Admin.ModuleDefinitions @inherits ModuleBase @using System.Globalization -@using Microsoft.AspNetCore.Localization @inject IModuleDefinitionService ModuleDefinitionService @inject IPackageService PackageService @inject ILanguageService LanguageService diff --git a/Oqtane.Client/Oqtane.Client.csproj b/Oqtane.Client/Oqtane.Client.csproj index 63a3743c..5860982c 100644 --- a/Oqtane.Client/Oqtane.Client.csproj +++ b/Oqtane.Client/Oqtane.Client.csproj @@ -26,7 +26,7 @@ - +
diff --git a/Oqtane.Client/Program.cs b/Oqtane.Client/Program.cs index 9f5ed2ff..d71131cb 100644 --- a/Oqtane.Client/Program.cs +++ b/Oqtane.Client/Program.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; @@ -13,13 +12,13 @@ using System.Text.Json; using System.Threading.Tasks; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; -using Microsoft.AspNetCore.Localization; using Microsoft.Extensions.DependencyInjection; using Microsoft.JSInterop; using Oqtane.Documentation; using Oqtane.Models; using Oqtane.Modules; using Oqtane.Services; +using Oqtane.Shared; using Oqtane.UI; namespace Oqtane.Client @@ -258,7 +257,7 @@ namespace Oqtane.Client var jsRuntime = serviceProvider.GetRequiredService(); var interop = new Interop(jsRuntime); var localizationCookie = await interop.GetCookie(CookieRequestCultureProvider.DefaultCookieName); - var culture = CookieRequestCultureProvider.ParseCookieValue(localizationCookie)?.UICultures?[0].Value; + var culture = CookieRequestCultureProvider.ParseCookieValue(localizationCookie)?.UICulture.Name; var localizationService = serviceProvider.GetRequiredService(); var cultures = await localizationService.GetCulturesAsync(false); diff --git a/Oqtane.Client/Themes/Controls/Theme/LanguageSwitcher.razor b/Oqtane.Client/Themes/Controls/Theme/LanguageSwitcher.razor index 78a6a99c..807ac9de 100644 --- a/Oqtane.Client/Themes/Controls/Theme/LanguageSwitcher.razor +++ b/Oqtane.Client/Themes/Controls/Theme/LanguageSwitcher.razor @@ -1,7 +1,6 @@ @using System.Globalization -@using Microsoft.AspNetCore.Localization -@using Microsoft.AspNetCore.Http @using Oqtane.Models +@using Microsoft.AspNetCore.Http @namespace Oqtane.Themes.Controls @inherits ThemeControlBase @inject ILanguageService LanguageService diff --git a/Oqtane.Server/Components/App.razor b/Oqtane.Server/Components/App.razor index 35d71322..d5eb3a3b 100644 --- a/Oqtane.Server/Components/App.razor +++ b/Oqtane.Server/Components/App.razor @@ -196,7 +196,7 @@ _bodyResources += ParseScripts(site.BodyContent); // set culture if not specified - string culture = Context.Request.Cookies[CookieRequestCultureProvider.DefaultCookieName]; + string culture = Context.Request.Cookies[Shared.CookieRequestCultureProvider.DefaultCookieName]; if (culture == null) { // get default language for site @@ -613,8 +613,8 @@ }; Context.Response.Cookies.Append( - CookieRequestCultureProvider.DefaultCookieName, - CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)), + Shared.CookieRequestCultureProvider.DefaultCookieName, + Shared.CookieRequestCultureProvider.MakeCookieValue(new Models.RequestCulture(culture)), cookieOptions ); } diff --git a/Oqtane.Shared/Models/RequestCulture.cs b/Oqtane.Shared/Models/RequestCulture.cs new file mode 100644 index 00000000..12eaaa7e --- /dev/null +++ b/Oqtane.Shared/Models/RequestCulture.cs @@ -0,0 +1,67 @@ +using System.Globalization; +using System; + +namespace Oqtane.Models +{ + /// + /// Culture information describing a Culture + /// + public class RequestCulture + { + /// + /// Creates a new object with its and + /// properties set to the same value. + /// + /// The for the request. + public RequestCulture(CultureInfo culture) + : this(culture, culture) + { + } + + /// + /// Creates a new object with its and + /// properties set to the same value. + /// + /// The culture for the request. + public RequestCulture(string culture) + : this(culture, culture) + { + } + + /// + /// Creates a new object with its and + /// properties set to the respective values provided. + /// + /// The culture for the request to be used for formatting. + /// The culture for the request to be used for text, i.e. language. + public RequestCulture(string culture, string uiCulture) + : this(new CultureInfo(culture), new CultureInfo(uiCulture)) + { + } + + /// + /// Creates a new object with its and + /// properties set to the respective values provided. + /// + /// The for the request to be used for formatting. + /// The for the request to be used for text, i.e. language. + public RequestCulture(CultureInfo culture, CultureInfo uiCulture) + { + ArgumentNullException.ThrowIfNull(culture); + ArgumentNullException.ThrowIfNull(uiCulture); + + Culture = culture; + UICulture = uiCulture; + } + + /// + /// Gets the for the request to be used for formatting. + /// + public CultureInfo Culture { get; } + + /// + /// Gets the for the request to be used for text, i.e. language; + /// + public CultureInfo UICulture { get; } + } +} diff --git a/Oqtane.Shared/Shared/CookieRequestCultureProvider.cs b/Oqtane.Shared/Shared/CookieRequestCultureProvider.cs new file mode 100644 index 00000000..040d43b3 --- /dev/null +++ b/Oqtane.Shared/Shared/CookieRequestCultureProvider.cs @@ -0,0 +1,89 @@ +using System; +using Oqtane.Models; + +namespace Oqtane.Shared +{ + public class CookieRequestCultureProvider + { + private const char _cookieSeparator = '|'; + private const string _culturePrefix = "c="; + private const string _uiCulturePrefix = "uic="; + + /// + /// Represent the default cookie name used to track the user's preferred culture information, which is ".AspNetCore.Culture". + /// + public static readonly string DefaultCookieName = ".AspNetCore.Culture"; + + /// + /// The name of the cookie that contains the user's preferred culture information. + /// Defaults to . + /// + public string CookieName { get; set; } = DefaultCookieName; + + /// + /// Creates a string representation of a for placement in a cookie. + /// + /// The . + /// The cookie value. + public static string MakeCookieValue(RequestCulture requestCulture) + { + ArgumentNullException.ThrowIfNull(requestCulture); + + return string.Join(_cookieSeparator, + $"{_culturePrefix}{requestCulture.Culture.Name}", + $"{_uiCulturePrefix}{requestCulture.UICulture.Name}"); + } + + /// + /// Parses a from the specified cookie value. + /// Returns null if parsing fails. + /// + /// The cookie value to parse. + /// The or null if parsing fails. + public static RequestCulture ParseCookieValue(string value) + { + if (string.IsNullOrWhiteSpace(value)) + { + return null; + } + + Span parts = stackalloc Range[3]; + var valueSpan = value.AsSpan(); + if (valueSpan.Split(parts, _cookieSeparator, StringSplitOptions.RemoveEmptyEntries) != 2) + { + return null; + } + + var potentialCultureName = valueSpan[parts[0]]; + var potentialUICultureName = valueSpan[parts[1]]; + + if (!potentialCultureName.StartsWith(_culturePrefix, StringComparison.Ordinal) || ! + potentialUICultureName.StartsWith(_uiCulturePrefix, StringComparison.Ordinal)) + { + return null; + } + + var cultureName = potentialCultureName.Slice(_culturePrefix.Length); + var uiCultureName = potentialUICultureName.Slice(_uiCulturePrefix.Length); + + if (cultureName.IsEmpty && uiCultureName.IsEmpty) + { + // No values specified for either so no match + return null; + } + + if (!cultureName.IsEmpty && uiCultureName.IsEmpty) + { + // Value for culture but not for UI culture so default to culture value for both + uiCultureName = cultureName; + } + else if (cultureName.IsEmpty && !uiCultureName.IsEmpty) + { + // Value for UI culture but not for culture so default to UI culture value for both + cultureName = uiCultureName; + } + + return new RequestCulture(cultureName.ToString(), uiCultureName.ToString()); + } + } +} From 588748230e305963ab1f144eb14266861ad540ac Mon Sep 17 00:00:00 2001 From: sbwalker Date: Thu, 24 Oct 2024 13:16:08 -0400 Subject: [PATCH 14/38] remove some dependencies on Microsoft.AspNetCore.Http --- Oqtane.Client/Services/RemoteServiceBase.cs | 5 ++--- Oqtane.Client/UI/SiteRouter.razor | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Oqtane.Client/Services/RemoteServiceBase.cs b/Oqtane.Client/Services/RemoteServiceBase.cs index 75c1435d..281d4d6c 100644 --- a/Oqtane.Client/Services/RemoteServiceBase.cs +++ b/Oqtane.Client/Services/RemoteServiceBase.cs @@ -4,7 +4,6 @@ using System.Net.Http; using System.Net.Http.Json; using System.Threading; using System.Threading.Tasks; -using Microsoft.Net.Http.Headers; using Oqtane.Shared; namespace Oqtane.Services @@ -28,9 +27,9 @@ namespace Oqtane.Services private HttpClient GetHttpClient(string AuthorizationToken) { var httpClient = _httpClientFactory.CreateClient("Remote"); - if (!httpClient.DefaultRequestHeaders.Contains(HeaderNames.Authorization) && !string.IsNullOrEmpty(AuthorizationToken)) + if (!httpClient.DefaultRequestHeaders.Contains("Authorization") && !string.IsNullOrEmpty(AuthorizationToken)) { - httpClient.DefaultRequestHeaders.Add(HeaderNames.Authorization, "Bearer " + AuthorizationToken); + httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + AuthorizationToken); } return httpClient; } diff --git a/Oqtane.Client/UI/SiteRouter.razor b/Oqtane.Client/UI/SiteRouter.razor index 0d5ebc1b..31ac6c21 100644 --- a/Oqtane.Client/UI/SiteRouter.razor +++ b/Oqtane.Client/UI/SiteRouter.razor @@ -1,6 +1,5 @@ @using System.Diagnostics.CodeAnalysis @using System.Net -@using Microsoft.AspNetCore.Http @using System.Globalization @using System.Security.Claims @namespace Oqtane.UI From 598d5decacc87be96b2aa9ea6cc005276b060bbb Mon Sep 17 00:00:00 2001 From: Cody Date: Thu, 24 Oct 2024 10:18:24 -0700 Subject: [PATCH 15/38] Update HtmlAgilityPack to 1.11.69 --- Oqtane.Server/Oqtane.Server.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Oqtane.Server/Oqtane.Server.csproj b/Oqtane.Server/Oqtane.Server.csproj index a78c8424..9ba7e370 100644 --- a/Oqtane.Server/Oqtane.Server.csproj +++ b/Oqtane.Server/Oqtane.Server.csproj @@ -46,7 +46,7 @@ - + From f09709aedb6d98549370ba6a82dbd22a52bf5338 Mon Sep 17 00:00:00 2001 From: sbwalker Date: Thu, 24 Oct 2024 15:10:52 -0400 Subject: [PATCH 16/38] remove Microsoft.AspNetCore.Http --- .../OqtaneServiceCollectionExtensions.cs | 1 + Oqtane.Client/Oqtane.Client.csproj | 1 - .../Interfaces/ILocalizationCookieService.cs | 17 +++++++++ .../Services/LocalizationCookieService.cs | 18 ++++++++++ .../Controls/Theme/LanguageSwitcher.razor | 19 ++-------- Oqtane.Client/UI/Routes.razor | 7 +--- .../OqtaneServiceCollectionExtensions.cs | 14 ++++---- .../Services/LocalizationCookieService.cs | 35 +++++++++++++++++++ 8 files changed, 83 insertions(+), 29 deletions(-) create mode 100644 Oqtane.Client/Services/Interfaces/ILocalizationCookieService.cs create mode 100644 Oqtane.Client/Services/LocalizationCookieService.cs create mode 100644 Oqtane.Server/Services/LocalizationCookieService.cs diff --git a/Oqtane.Client/Extensions/OqtaneServiceCollectionExtensions.cs b/Oqtane.Client/Extensions/OqtaneServiceCollectionExtensions.cs index 8facf91f..457af666 100644 --- a/Oqtane.Client/Extensions/OqtaneServiceCollectionExtensions.cs +++ b/Oqtane.Client/Extensions/OqtaneServiceCollectionExtensions.cs @@ -51,6 +51,7 @@ namespace Microsoft.Extensions.DependencyInjection services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); // providers services.AddScoped(); diff --git a/Oqtane.Client/Oqtane.Client.csproj b/Oqtane.Client/Oqtane.Client.csproj index 5860982c..99a738b1 100644 --- a/Oqtane.Client/Oqtane.Client.csproj +++ b/Oqtane.Client/Oqtane.Client.csproj @@ -26,7 +26,6 @@ - diff --git a/Oqtane.Client/Services/Interfaces/ILocalizationCookieService.cs b/Oqtane.Client/Services/Interfaces/ILocalizationCookieService.cs new file mode 100644 index 00000000..a422d432 --- /dev/null +++ b/Oqtane.Client/Services/Interfaces/ILocalizationCookieService.cs @@ -0,0 +1,17 @@ +using System.Threading.Tasks; + +namespace Oqtane.Services +{ + /// + /// Service to set localization cookie + /// + public interface ILocalizationCookieService + { + /// + /// Set the localization cookie + /// + /// + /// + Task SetLocalizationCookieAsync(string culture); + } +} diff --git a/Oqtane.Client/Services/LocalizationCookieService.cs b/Oqtane.Client/Services/LocalizationCookieService.cs new file mode 100644 index 00000000..330607e6 --- /dev/null +++ b/Oqtane.Client/Services/LocalizationCookieService.cs @@ -0,0 +1,18 @@ +using System.Net.Http; +using System.Threading.Tasks; +using Oqtane.Documentation; +using Oqtane.Shared; + +namespace Oqtane.Services +{ + [PrivateApi("Don't show in the documentation, as everything should use the Interface")] + public class LocalizationCookieService : ServiceBase, ILocalizationCookieService + { + public LocalizationCookieService(HttpClient http, SiteState siteState) : base(http, siteState) { } + + public Task SetLocalizationCookieAsync(string culture) + { + return Task.CompletedTask; // only used in server side rendering + } + } +} diff --git a/Oqtane.Client/Themes/Controls/Theme/LanguageSwitcher.razor b/Oqtane.Client/Themes/Controls/Theme/LanguageSwitcher.razor index 807ac9de..eaf3f48c 100644 --- a/Oqtane.Client/Themes/Controls/Theme/LanguageSwitcher.razor +++ b/Oqtane.Client/Themes/Controls/Theme/LanguageSwitcher.razor @@ -1,9 +1,9 @@ @using System.Globalization @using Oqtane.Models -@using Microsoft.AspNetCore.Http @namespace Oqtane.Themes.Controls @inherits ThemeControlBase @inject ILanguageService LanguageService +@inject ILocalizationCookieService LocalizationCookieService @inject NavigationManager NavigationManager @if (_supportedCultures?.Count() > 1) @@ -37,10 +37,7 @@ [Parameter] public string ButtonClass { get; set; } = "btn-outline-secondary"; - [CascadingParameter] - HttpContext HttpContext { get; set; } - - protected override void OnParametersSet() + protected override async Task OnParametersSetAsync() { MenuAlignment = DropdownAlignment.ToLower() == "right" ? "dropdown-menu-end" : string.Empty; @@ -51,17 +48,7 @@ var culture = PageState.QueryString["culture"]; if (_supportedCultures.Any(item => item.Name == culture)) { - var localizationCookieValue = CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)); - - HttpContext.Response.Cookies.Append(CookieRequestCultureProvider.DefaultCookieName, localizationCookieValue, new CookieOptions - { - Path = "/", - Expires = DateTimeOffset.UtcNow.AddYears(365), - SameSite = Microsoft.AspNetCore.Http.SameSiteMode.Lax, // Set SameSite attribute - Secure = true, // Ensure the cookie is only sent over HTTPS - HttpOnly = false // cookie is updated using JS Interop in Interactive render mode - }); - + await LocalizationCookieService.SetLocalizationCookieAsync(culture); } NavigationManager.NavigateTo(NavigationManager.Uri.Replace($"?culture={culture}", "")); } diff --git a/Oqtane.Client/UI/Routes.razor b/Oqtane.Client/UI/Routes.razor index de6503f2..20dc0a09 100644 --- a/Oqtane.Client/UI/Routes.razor +++ b/Oqtane.Client/UI/Routes.razor @@ -1,7 +1,5 @@ @namespace Oqtane.UI -@using Microsoft.AspNetCore.Http @inject IInstallationService InstallationService -@inject IJSRuntime JSRuntime @inject SiteState SiteState @if (_initialized) @@ -48,9 +46,6 @@ [Parameter] public string Platform { get; set; } = ""; - [CascadingParameter] - HttpContext HttpContext { get; set; } - private bool _initialized = false; private bool _installed = false; private string _display = "display: none;"; @@ -62,7 +57,7 @@ SiteState.AntiForgeryToken = AntiForgeryToken; SiteState.AuthorizationToken = AuthorizationToken; SiteState.Platform = Platform; - SiteState.IsPrerendering = (HttpContext != null) ? true : false; + SiteState.IsPrerendering = !RendererInfo.IsInteractive; if (Runtime == Runtimes.Hybrid) { diff --git a/Oqtane.Server/Extensions/OqtaneServiceCollectionExtensions.cs b/Oqtane.Server/Extensions/OqtaneServiceCollectionExtensions.cs index 2b03eec6..b04f2061 100644 --- a/Oqtane.Server/Extensions/OqtaneServiceCollectionExtensions.cs +++ b/Oqtane.Server/Extensions/OqtaneServiceCollectionExtensions.cs @@ -113,8 +113,11 @@ namespace Microsoft.Extensions.DependencyInjection internal static IServiceCollection AddOqtaneTransientServices(this IServiceCollection services) { - // repositories + // services services.AddTransient(); + services.AddTransient(); + + // repositories services.AddTransient(); services.AddTransient(); services.AddTransient(); @@ -130,7 +133,6 @@ namespace Microsoft.Extensions.DependencyInjection services.AddTransient(); services.AddTransient(); services.AddTransient(); - services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); @@ -153,12 +155,12 @@ namespace Microsoft.Extensions.DependencyInjection services.AddTransient(); services.AddTransient(); services.AddTransient(); - - // obsolete - replaced by ITenantManager - services.AddTransient(); - + services.AddTransient(); services.AddTransient(); + // obsolete + services.AddTransient(); // replaced by ITenantManager + return services; } diff --git a/Oqtane.Server/Services/LocalizationCookieService.cs b/Oqtane.Server/Services/LocalizationCookieService.cs new file mode 100644 index 00000000..1bedfc6f --- /dev/null +++ b/Oqtane.Server/Services/LocalizationCookieService.cs @@ -0,0 +1,35 @@ +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Localization; +using Oqtane.Documentation; + +namespace Oqtane.Services +{ + [PrivateApi("Don't show in the documentation, as everything should use the Interface")] + public class ServerLocalizationCookieService : ILocalizationCookieService + { + private readonly IHttpContextAccessor _accessor; + + public ServerLocalizationCookieService(IHttpContextAccessor accessor) + { + _accessor = accessor; + } + + public Task SetLocalizationCookieAsync(string culture) + { + var localizationCookieValue = CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)); + + _accessor.HttpContext.Response.Cookies.Append(CookieRequestCultureProvider.DefaultCookieName, localizationCookieValue, new CookieOptions + { + Path = "/", + Expires = DateTimeOffset.UtcNow.AddYears(365), + SameSite = SameSiteMode.Lax, + Secure = true, // Ensure the cookie is only sent over HTTPS + HttpOnly = false // cookie is updated using JS Interop in Interactive render mode + }); + + return Task.CompletedTask; + } + } +} From b0c8203b24ed7f61ee4174c157704875dff0219b Mon Sep 17 00:00:00 2001 From: sbwalker Date: Thu, 24 Oct 2024 15:20:07 -0400 Subject: [PATCH 17/38] remove Microsoft.AspNetCore.Localization from default module template --- .../External/Client/[Owner].Module.[Module].Client.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/Oqtane.Server/wwwroot/Modules/Templates/External/Client/[Owner].Module.[Module].Client.csproj b/Oqtane.Server/wwwroot/Modules/Templates/External/Client/[Owner].Module.[Module].Client.csproj index 0c3de498..15b5998d 100644 --- a/Oqtane.Server/wwwroot/Modules/Templates/External/Client/[Owner].Module.[Module].Client.csproj +++ b/Oqtane.Server/wwwroot/Modules/Templates/External/Client/[Owner].Module.[Module].Client.csproj @@ -17,7 +17,6 @@ - From 0dfdb124311c828fab807bc0568b3f4d83d72b41 Mon Sep 17 00:00:00 2001 From: sbwalker Date: Thu, 24 Oct 2024 15:48:14 -0400 Subject: [PATCH 18/38] get language using CookieRequestCultureProvider --- Oqtane.Server/Components/App.razor | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Oqtane.Server/Components/App.razor b/Oqtane.Server/Components/App.razor index d5eb3a3b..369dfd16 100644 --- a/Oqtane.Server/Components/App.razor +++ b/Oqtane.Server/Components/App.razor @@ -215,9 +215,7 @@ // set language for page if (!string.IsNullOrEmpty(culture)) { - // localization cookie value in form of c=en|uic=en - _language = culture.Split('|')[0]; - _language = _language.Replace("c=", ""); + _language = Shared.CookieRequestCultureProvider.ParseCookieValue(culture).Culture.Name; } // create initial PageState From 7deb0b06afc33972b907066f536943926d5ca5d5 Mon Sep 17 00:00:00 2001 From: sbwalker Date: Thu, 24 Oct 2024 17:08:25 -0400 Subject: [PATCH 19/38] fix #4770 - set a default value for PrincipalSchema to ensure backward compatibility --- Oqtane.Server/Migrations/Framework/ForeignKey.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Oqtane.Server/Migrations/Framework/ForeignKey.cs b/Oqtane.Server/Migrations/Framework/ForeignKey.cs index 5f1bcd75..0a7e9e7f 100644 --- a/Oqtane.Server/Migrations/Framework/ForeignKey.cs +++ b/Oqtane.Server/Migrations/Framework/ForeignKey.cs @@ -44,7 +44,7 @@ namespace Oqtane.Migrations public string PrincipalColumn { get; } - public string PrincipalSchema { get; } + public string PrincipalSchema { get; } = ""; } From 89312c67966eca7b3357d1be74b8829a23e51d3f Mon Sep 17 00:00:00 2001 From: Cody Date: Wed, 30 Oct 2024 18:43:42 -0700 Subject: [PATCH 20/38] Update Oqtane.Server.csproj Package Dependencies --- Oqtane.Server/Oqtane.Server.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Oqtane.Server/Oqtane.Server.csproj b/Oqtane.Server/Oqtane.Server.csproj index 9ba7e370..430b24af 100644 --- a/Oqtane.Server/Oqtane.Server.csproj +++ b/Oqtane.Server/Oqtane.Server.csproj @@ -35,7 +35,7 @@ - + all @@ -46,7 +46,7 @@ - + From c8a22d9537b02c5458ef53966778cf273ebe86ae Mon Sep 17 00:00:00 2001 From: sbwalker Date: Mon, 4 Nov 2024 15:28:59 -0500 Subject: [PATCH 21/38] fix #4795 - ensure deterministic ordering of file parts when merging files after upload (credit @HQuast) --- Oqtane.Server/Controllers/FileController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Oqtane.Server/Controllers/FileController.cs b/Oqtane.Server/Controllers/FileController.cs index 1e8a1740..70d17d1d 100644 --- a/Oqtane.Server/Controllers/FileController.cs +++ b/Oqtane.Server/Controllers/FileController.cs @@ -517,7 +517,7 @@ namespace Oqtane.Controllers bool success = true; using (var stream = new FileStream(Path.Combine(folder, filename + ".tmp"), FileMode.Create)) { - foreach (string filepart in fileparts) + foreach (string filepart in fileparts.Order()) { try { From d85a2fc8cecb3182def0625a470f980af6b47d82 Mon Sep 17 00:00:00 2001 From: sbwalker Date: Tue, 5 Nov 2024 11:30:18 -0500 Subject: [PATCH 22/38] remove custom JavaScript reconnection script for SignalR --- Oqtane.Server/Components/App.razor | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/Oqtane.Server/Components/App.razor b/Oqtane.Server/Components/App.razor index 369dfd16..3747b66f 100644 --- a/Oqtane.Server/Components/App.razor +++ b/Oqtane.Server/Components/App.razor @@ -179,10 +179,6 @@ ManageScripts(resources, alias); // generate scripts - if (_renderMode == RenderModes.Interactive && _runtime == Runtimes.Server) - { - _scripts += CreateReconnectScript(); - } if (site.PwaIsEnabled && site.PwaAppIconFileId != null && site.PwaSplashIconFileId != null) { _scripts += CreatePWAScript(alias, site, route); @@ -492,25 +488,6 @@ "" + Environment.NewLine; } - private string CreateReconnectScript() - { - return Environment.NewLine + - "" + Environment.NewLine; - } - private string CreateScrollPositionScript() { return Environment.NewLine + From 18b1b5fca58c42a6e6cf8cfe2c0c5814f3ac1ec8 Mon Sep 17 00:00:00 2001 From: sbwalker Date: Thu, 7 Nov 2024 11:52:53 -0500 Subject: [PATCH 23/38] default Description to Module Name if not specified in Module Creator --- Oqtane.Client/Modules/Admin/ModuleDefinitions/Create.razor | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Create.razor b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Create.razor index f673ca10..60241e2a 100644 --- a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Create.razor +++ b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Create.razor @@ -27,7 +27,7 @@
- +
@@ -118,6 +118,7 @@ { if (IsValid(_owner) && IsValid(_module) && _owner != _module && _template != "-") { + if (string.IsNullOrEmpty(_description)) _description = _module; if (IsValidXML(_description)) { var template = _templates.FirstOrDefault(item => item.Name == _template); From f46ac2c0077f805778b2f8f98acd2d5773b3495f Mon Sep 17 00:00:00 2001 From: sbwalker Date: Thu, 7 Nov 2024 12:38:16 -0500 Subject: [PATCH 24/38] remove icrosoft.AspNetCore.Localization from .NET MAUI project --- Oqtane.Maui/Oqtane.Maui.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/Oqtane.Maui/Oqtane.Maui.csproj b/Oqtane.Maui/Oqtane.Maui.csproj index 5f05face..fa7ecb9e 100644 --- a/Oqtane.Maui/Oqtane.Maui.csproj +++ b/Oqtane.Maui/Oqtane.Maui.csproj @@ -67,7 +67,6 @@ - From 013056a6e5dc9d26e3ed08f459fb9d968aa26af1 Mon Sep 17 00:00:00 2001 From: sbwalker Date: Thu, 7 Nov 2024 15:45:34 -0500 Subject: [PATCH 25/38] fix compilation warning --- Oqtane.Maui/App.xaml.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Oqtane.Maui/App.xaml.cs b/Oqtane.Maui/App.xaml.cs index 4a344371..95ffaf1b 100644 --- a/Oqtane.Maui/App.xaml.cs +++ b/Oqtane.Maui/App.xaml.cs @@ -7,7 +7,7 @@ public partial class App : Application InitializeComponent(); } - protected override Window CreateWindow(IActivationState? activationState) + protected override Window CreateWindow(IActivationState activationState) { return new Window(new MainPage()); } From fdbdd0ef4c34dcc1b164090b736424d3daeb941f Mon Sep 17 00:00:00 2001 From: sbwalker Date: Thu, 7 Nov 2024 17:05:28 -0500 Subject: [PATCH 26/38] Added defensive logic to File Indexer for scenarios where file does not exist on disk. Added ability to reset the search index prior to reindexing. --- .../Modules/Admin/Search/Index.razor | 4 +--- .../Infrastructure/Jobs/SearchIndexJob.cs | 7 +++++++ .../Admin/Files/Manager/FileManager.cs | 21 ++++++++++++++++--- .../Providers/DatabaseSearchProvider.cs | 4 ++-- .../Interfaces/ISearchContentRepository.cs | 2 +- .../Repository/SearchContentRepository.cs | 12 ++++++++--- Oqtane.Server/Services/SearchService.cs | 6 ++++++ Oqtane.Shared/Interfaces/ISearchProvider.cs | 4 ++-- Oqtane.Shared/Interfaces/ISearchService.cs | 2 ++ 9 files changed, 48 insertions(+), 14 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Search/Index.razor b/Oqtane.Client/Modules/Admin/Search/Index.razor index 8a32ff22..88653cca 100644 --- a/Oqtane.Client/Modules/Admin/Search/Index.razor +++ b/Oqtane.Client/Modules/Admin/Search/Index.razor @@ -106,9 +106,7 @@ try { _lastIndexedOn = DateTime.MinValue.ToString(); - var settings = await SettingService.GetSiteSettingsAsync(PageState.Site.SiteId); - settings = SettingService.SetSetting(settings, "Search_LastIndexedOn", _lastIndexedOn, true); - await SettingService.UpdateSiteSettingsAsync(settings, PageState.Site.SiteId); + await Save(); AddModuleMessage(Localizer["Message.Reindex"], MessageType.Success); } catch (Exception ex) diff --git a/Oqtane.Server/Infrastructure/Jobs/SearchIndexJob.cs b/Oqtane.Server/Infrastructure/Jobs/SearchIndexJob.cs index 21b28e40..22e16f0f 100644 --- a/Oqtane.Server/Infrastructure/Jobs/SearchIndexJob.cs +++ b/Oqtane.Server/Infrastructure/Jobs/SearchIndexJob.cs @@ -59,6 +59,13 @@ namespace Oqtane.Infrastructure var currentTime = DateTime.UtcNow; var lastIndexedOn = Convert.ToDateTime(siteSettings.GetValue(SearchLastIndexedOnSetting, DateTime.MinValue.ToString())); + if (lastIndexedOn == DateTime.MinValue) + { + // reset index + log += $"*Site Index Reset*
"; + await searchService.DeleteSearchContentsAsync(site.SiteId); + } + var ignorePages = siteSettings.GetValue(SearchIgnorePagesSetting, "").Split(','); var ignoreEntities = siteSettings.GetValue(SearchIgnoreEntitiesSetting, "").Split(','); diff --git a/Oqtane.Server/Modules/Admin/Files/Manager/FileManager.cs b/Oqtane.Server/Modules/Admin/Files/Manager/FileManager.cs index 96b75879..43dbda33 100644 --- a/Oqtane.Server/Modules/Admin/Files/Manager/FileManager.cs +++ b/Oqtane.Server/Modules/Admin/Files/Manager/FileManager.cs @@ -45,10 +45,25 @@ namespace Oqtane.Modules.Admin.Files.Manager var path = folder.Path + file.Name; var body = ""; - if (DocumentExtensions.Contains(Path.GetExtension(file.Name))) + if (System.IO.File.Exists(_fileRepository.GetFilePath(file))) { - // get the contents of the file - body = System.IO.File.ReadAllText(_fileRepository.GetFilePath(file)); + // only non-binary files can be indexed + if (DocumentExtensions.Contains(Path.GetExtension(file.Name))) + { + // get the contents of the file + try + { + body = System.IO.File.ReadAllText(_fileRepository.GetFilePath(file)); + } + catch + { + // could not read the file + } + } + } + else + { + removed = true; // file does not exist on disk } var searchContent = new SearchContent diff --git a/Oqtane.Server/Providers/DatabaseSearchProvider.cs b/Oqtane.Server/Providers/DatabaseSearchProvider.cs index c3e5d28e..a662b106 100644 --- a/Oqtane.Server/Providers/DatabaseSearchProvider.cs +++ b/Oqtane.Server/Providers/DatabaseSearchProvider.cs @@ -235,9 +235,9 @@ namespace Oqtane.Providers return text; } - public Task ResetIndex() + public Task DeleteSearchContent(int siteId) { - _searchContentRepository.DeleteAllSearchContent(); + _searchContentRepository.DeleteAllSearchContent(siteId); return Task.CompletedTask; } } diff --git a/Oqtane.Server/Repository/Interfaces/ISearchContentRepository.cs b/Oqtane.Server/Repository/Interfaces/ISearchContentRepository.cs index 8511b438..022c8012 100644 --- a/Oqtane.Server/Repository/Interfaces/ISearchContentRepository.cs +++ b/Oqtane.Server/Repository/Interfaces/ISearchContentRepository.cs @@ -12,7 +12,7 @@ namespace Oqtane.Repository void DeleteSearchContent(int searchContentId); void DeleteSearchContent(string entityName, string entryId); void DeleteSearchContent(string uniqueKey); - void DeleteAllSearchContent(); + void DeleteAllSearchContent(int siteId); SearchWord GetSearchWord(string word); SearchWord AddSearchWord(SearchWord searchWord); diff --git a/Oqtane.Server/Repository/SearchContentRepository.cs b/Oqtane.Server/Repository/SearchContentRepository.cs index 53d736a5..5aa214ae 100644 --- a/Oqtane.Server/Repository/SearchContentRepository.cs +++ b/Oqtane.Server/Repository/SearchContentRepository.cs @@ -152,11 +152,17 @@ namespace Oqtane.Repository } } - public void DeleteAllSearchContent() + public void DeleteAllSearchContent(int siteId) { using var db = _dbContextFactory.CreateDbContext(); - db.SearchContent.RemoveRange(db.SearchContent); - db.SaveChanges(); + // delete in batches of 100 records + var searchContents = db.SearchContent.Where(item => item.SiteId == siteId).Take(100).ToList(); + while (searchContents.Count > 0) + { + db.SearchContent.RemoveRange(searchContents); + db.SaveChanges(); + searchContents = db.SearchContent.Where(item => item.SiteId == siteId).Take(100).ToList(); + } } public SearchWord GetSearchWord(string word) diff --git a/Oqtane.Server/Services/SearchService.cs b/Oqtane.Server/Services/SearchService.cs index 528f48e1..9a4f7ea1 100644 --- a/Oqtane.Server/Services/SearchService.cs +++ b/Oqtane.Server/Services/SearchService.cs @@ -149,6 +149,12 @@ namespace Oqtane.Services return result; } + public async Task DeleteSearchContentsAsync(int siteId) + { + var searchProvider = GetSearchProvider(siteId); + await searchProvider.DeleteSearchContent(siteId); + } + private ISearchProvider GetSearchProvider(int siteId) { var providerName = GetSearchProviderSetting(siteId); diff --git a/Oqtane.Shared/Interfaces/ISearchProvider.cs b/Oqtane.Shared/Interfaces/ISearchProvider.cs index 43981e8d..23713334 100644 --- a/Oqtane.Shared/Interfaces/ISearchProvider.cs +++ b/Oqtane.Shared/Interfaces/ISearchProvider.cs @@ -11,7 +11,7 @@ namespace Oqtane.Services Task> GetSearchResultsAsync(SearchQuery searchQuery); Task SaveSearchContent(SearchContent searchContent, Dictionary siteSettings); - - Task ResetIndex(); + + Task DeleteSearchContent(int siteId); } } diff --git a/Oqtane.Shared/Interfaces/ISearchService.cs b/Oqtane.Shared/Interfaces/ISearchService.cs index 48cef29c..7acf9764 100644 --- a/Oqtane.Shared/Interfaces/ISearchService.cs +++ b/Oqtane.Shared/Interfaces/ISearchService.cs @@ -9,5 +9,7 @@ namespace Oqtane.Services Task GetSearchResultsAsync(SearchQuery searchQuery); Task SaveSearchContentsAsync(List searchContents, Dictionary siteSettings); + + Task DeleteSearchContentsAsync(int siteId); } } From 0f698e0c5044b03232da16b52722aed21ee2b3f8 Mon Sep 17 00:00:00 2001 From: sbwalker Date: Fri, 8 Nov 2024 15:16:32 -0500 Subject: [PATCH 27/38] make indexing of Files opt-in rather than opt-out --- Oqtane.Client/Modules/Admin/Search/Index.razor | 2 +- Oqtane.Client/Resources/Modules/Admin/Search/Index.resx | 4 ++-- Oqtane.Server/Infrastructure/Jobs/SearchIndexJob.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Search/Index.razor b/Oqtane.Client/Modules/Admin/Search/Index.razor index 88653cca..57caa1aa 100644 --- a/Oqtane.Client/Modules/Admin/Search/Index.razor +++ b/Oqtane.Client/Modules/Admin/Search/Index.razor @@ -63,7 +63,7 @@ private string _enabled = "True"; private string _lastIndexedOn = ""; private string _ignorePages = ""; - private string _ignoreEntities = ""; + private string _ignoreEntities = "File"; private string _minimumWordLength = "3"; private string _ignoreWords = "the,be,to,of,and,a,i,in,that,have,it,for,not,on,with,he,as,you,do,at,this,but,his,by,from,they,we,say,her,she,or,an,will,my,one,all,would,there,their,what,so,up,out,if,about,who,get,which,go,me,when,make,can,like,time,no,just,him,know,take,people,into,year,your,good,some,could,them,see,other,than,then,now,look,only,come,its,over,think,also,back,after,use,two,how,our,work,first,well,way,even,new,want,because,any,these,give,day,most,us"; diff --git a/Oqtane.Client/Resources/Modules/Admin/Search/Index.resx b/Oqtane.Client/Resources/Modules/Admin/Search/Index.resx index 0f8e26f4..e9c7d34f 100644 --- a/Oqtane.Client/Resources/Modules/Admin/Search/Index.resx +++ b/Oqtane.Client/Resources/Modules/Admin/Search/Index.resx @@ -139,7 +139,7 @@ Ignore Entities: - Comma delimited list of entities which should be ignored + Comma delimited list of entities which should be ignored. By default File entities are ignored. Word Length: @@ -154,7 +154,7 @@ Comma delimited list of words which should be ignored - Search Settings Saved Successfully + Search Settings Saved Successfully. You Will Need Reindex For Your Changes To Be Reflected In The Search Results. Error Saving Search Settings diff --git a/Oqtane.Server/Infrastructure/Jobs/SearchIndexJob.cs b/Oqtane.Server/Infrastructure/Jobs/SearchIndexJob.cs index 22e16f0f..9b2d2f83 100644 --- a/Oqtane.Server/Infrastructure/Jobs/SearchIndexJob.cs +++ b/Oqtane.Server/Infrastructure/Jobs/SearchIndexJob.cs @@ -67,7 +67,7 @@ namespace Oqtane.Infrastructure } var ignorePages = siteSettings.GetValue(SearchIgnorePagesSetting, "").Split(','); - var ignoreEntities = siteSettings.GetValue(SearchIgnoreEntitiesSetting, "").Split(','); + var ignoreEntities = siteSettings.GetValue(SearchIgnoreEntitiesSetting, "File").Split(','); var pages = pageRepository.GetPages(site.SiteId); var pageModules = pageModuleRepository.GetPageModules(site.SiteId); From 5a91b143b604ead3a3988aecbdd6a86e3622dc46 Mon Sep 17 00:00:00 2001 From: sbwalker Date: Fri, 8 Nov 2024 15:41:24 -0500 Subject: [PATCH 28/38] resolved issue when setting initial culture cookie --- Oqtane.Server/Components/App.razor | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/Oqtane.Server/Components/App.razor b/Oqtane.Server/Components/App.razor index 3747b66f..e8c7ca76 100644 --- a/Oqtane.Server/Components/App.razor +++ b/Oqtane.Server/Components/App.razor @@ -192,26 +192,29 @@ _bodyResources += ParseScripts(site.BodyContent); // set culture if not specified - string culture = Context.Request.Cookies[Shared.CookieRequestCultureProvider.DefaultCookieName]; - if (culture == null) + string cultureCookie = Context.Request.Cookies[Shared.CookieRequestCultureProvider.DefaultCookieName]; + if (cultureCookie == null) { // get default language for site if (site.Languages.Any()) { // use default language if specified otherwise use first language in collection - culture = (site.Languages.Where(l => l.IsDefault).SingleOrDefault() ?? site.Languages.First()).Code; + cultureCookie = (site.Languages.Where(l => l.IsDefault).SingleOrDefault() ?? site.Languages.First()).Code; } else { - culture = LocalizationManager.GetDefaultCulture(); + // fallback language + cultureCookie = LocalizationManager.GetDefaultCulture(); } - SetLocalizationCookie(culture); + // convert language code to culture cookie format (ie. "c=en|uic=en") + cultureCookie = Shared.CookieRequestCultureProvider.MakeCookieValue(new Models.RequestCulture(cultureCookie)); + SetLocalizationCookie(cultureCookie); } // set language for page - if (!string.IsNullOrEmpty(culture)) + if (!string.IsNullOrEmpty(cultureCookie)) { - _language = Shared.CookieRequestCultureProvider.ParseCookieValue(culture).Culture.Name; + _language = Shared.CookieRequestCultureProvider.ParseCookieValue(cultureCookie).Culture.Name; } // create initial PageState @@ -577,7 +580,7 @@ } } - private void SetLocalizationCookie(string culture) + private void SetLocalizationCookie(string cookieValue) { var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions { @@ -589,7 +592,7 @@ Context.Response.Cookies.Append( Shared.CookieRequestCultureProvider.DefaultCookieName, - Shared.CookieRequestCultureProvider.MakeCookieValue(new Models.RequestCulture(culture)), + cookieValue, cookieOptions ); } From 422bf8da59646c344c8db6eb83b5feb3bcc0cad4 Mon Sep 17 00:00:00 2001 From: sbwalker Date: Mon, 11 Nov 2024 08:14:53 -0500 Subject: [PATCH 29/38] use HttpClient rather than IHttpClientFactory as IHttpClientFactory does not pass cookies in .NET MAUI --- .../Templates/External/Client/Services/[Module]Service.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Oqtane.Server/wwwroot/Modules/Templates/External/Client/Services/[Module]Service.cs b/Oqtane.Server/wwwroot/Modules/Templates/External/Client/Services/[Module]Service.cs index 0161a66b..23f10772 100644 --- a/Oqtane.Server/wwwroot/Modules/Templates/External/Client/Services/[Module]Service.cs +++ b/Oqtane.Server/wwwroot/Modules/Templates/External/Client/Services/[Module]Service.cs @@ -9,7 +9,7 @@ namespace [Owner].Module.[Module].Services { public class [Module]Service : ServiceBase, I[Module]Service { - public [Module]Service(IHttpClientFactory http, SiteState siteState) : base(http, siteState) { } + public [Module]Service(HttpClient http, SiteState siteState) : base(http, siteState) { } private string Apiurl => CreateApiUrl("[Module]"); From ab807de3c010610a846cd26b6e0c7bbeb71670ed Mon Sep 17 00:00:00 2001 From: David Montesinos <90258222+mdmontesinos@users.noreply.github.com> Date: Tue, 12 Nov 2024 17:15:56 +0100 Subject: [PATCH 30/38] Fix: Accesibility issue for Search Button The search button in Search component does not have the aria-label. --- Oqtane.Client/Themes/Controls/Theme/Search.razor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Oqtane.Client/Themes/Controls/Theme/Search.razor b/Oqtane.Client/Themes/Controls/Theme/Search.razor index 19eec4cc..ccb4b327 100644 --- a/Oqtane.Client/Themes/Controls/Theme/Search.razor +++ b/Oqtane.Client/Themes/Controls/Theme/Search.razor @@ -18,7 +18,7 @@ placeholder="@Localizer["SearchPlaceHolder"]" aria-label="Search" /> } - From 0f2aa4d2e1ae5796b394c5d395a74c6888b613a9 Mon Sep 17 00:00:00 2001 From: sbwalker Date: Tue, 12 Nov 2024 15:40:54 -0500 Subject: [PATCH 31/38] update to official .NET 9 release --- .../Modules/Controls/FileManager.razor | 6 +++--- Oqtane.Client/Oqtane.Client.csproj | 8 ++++---- .../Oqtane.Database.SqlServer.csproj | 2 +- .../Oqtane.Database.Sqlite.csproj | 2 +- Oqtane.Maui/Oqtane.Maui.csproj | 16 ++++++++-------- Oqtane.Server/Oqtane.Server.csproj | 18 +++++++++--------- .../[Owner].Module.[Module].Client.csproj | 10 +++++----- .../[Owner].Module.[Module].Server.csproj | 8 ++++---- .../Client/[Owner].Theme.[Theme].Client.csproj | 6 +++--- Oqtane.Shared/Oqtane.Shared.csproj | 8 ++++---- 10 files changed, 42 insertions(+), 42 deletions(-) diff --git a/Oqtane.Client/Modules/Controls/FileManager.razor b/Oqtane.Client/Modules/Controls/FileManager.razor index a52f359e..509cef2d 100644 --- a/Oqtane.Client/Modules/Controls/FileManager.razor +++ b/Oqtane.Client/Modules/Controls/FileManager.razor @@ -196,7 +196,7 @@ else { FolderId = -1; - _message = "Folder Path " + Folder + "Does Not Exist"; + _message = "Folder Path " + Folder + " Does Not Exist"; _messagetype = MessageType.Error; } } @@ -226,9 +226,9 @@ } else { - FileId = -1; // file does not exist - _message = "FileId " + FileId.ToString() + "Does Not Exist"; + _message = "FileId " + FileId.ToString() + " Does Not Exist"; _messagetype = MessageType.Error; + FileId = -1; // file does not exist } } diff --git a/Oqtane.Client/Oqtane.Client.csproj b/Oqtane.Client/Oqtane.Client.csproj index 99a738b1..4823e285 100644 --- a/Oqtane.Client/Oqtane.Client.csproj +++ b/Oqtane.Client/Oqtane.Client.csproj @@ -22,10 +22,10 @@ - - - - + + + + diff --git a/Oqtane.Database.SqlServer/Oqtane.Database.SqlServer.csproj b/Oqtane.Database.SqlServer/Oqtane.Database.SqlServer.csproj index 69c82da2..8c5a767b 100644 --- a/Oqtane.Database.SqlServer/Oqtane.Database.SqlServer.csproj +++ b/Oqtane.Database.SqlServer/Oqtane.Database.SqlServer.csproj @@ -33,7 +33,7 @@ - + diff --git a/Oqtane.Database.Sqlite/Oqtane.Database.Sqlite.csproj b/Oqtane.Database.Sqlite/Oqtane.Database.Sqlite.csproj index 6ff145b1..254b21db 100644 --- a/Oqtane.Database.Sqlite/Oqtane.Database.Sqlite.csproj +++ b/Oqtane.Database.Sqlite/Oqtane.Database.Sqlite.csproj @@ -33,7 +33,7 @@ - + diff --git a/Oqtane.Maui/Oqtane.Maui.csproj b/Oqtane.Maui/Oqtane.Maui.csproj index fa7ecb9e..1cbd246f 100644 --- a/Oqtane.Maui/Oqtane.Maui.csproj +++ b/Oqtane.Maui/Oqtane.Maui.csproj @@ -65,14 +65,14 @@ - - - - - - - - + + + + + + + + diff --git a/Oqtane.Server/Oqtane.Server.csproj b/Oqtane.Server/Oqtane.Server.csproj index a78c8424..e4b5a55f 100644 --- a/Oqtane.Server/Oqtane.Server.csproj +++ b/Oqtane.Server/Oqtane.Server.csproj @@ -33,20 +33,20 @@ - - - - - + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + + - + diff --git a/Oqtane.Server/wwwroot/Modules/Templates/External/Client/[Owner].Module.[Module].Client.csproj b/Oqtane.Server/wwwroot/Modules/Templates/External/Client/[Owner].Module.[Module].Client.csproj index 15b5998d..0bc7b7c7 100644 --- a/Oqtane.Server/wwwroot/Modules/Templates/External/Client/[Owner].Module.[Module].Client.csproj +++ b/Oqtane.Server/wwwroot/Modules/Templates/External/Client/[Owner].Module.[Module].Client.csproj @@ -13,11 +13,11 @@ - - - - - + + + + + diff --git a/Oqtane.Server/wwwroot/Modules/Templates/External/Server/[Owner].Module.[Module].Server.csproj b/Oqtane.Server/wwwroot/Modules/Templates/External/Server/[Owner].Module.[Module].Server.csproj index 7f0a1262..550e7e32 100644 --- a/Oqtane.Server/wwwroot/Modules/Templates/External/Server/[Owner].Module.[Module].Server.csproj +++ b/Oqtane.Server/wwwroot/Modules/Templates/External/Server/[Owner].Module.[Module].Server.csproj @@ -19,10 +19,10 @@ - - - - + + + + diff --git a/Oqtane.Server/wwwroot/Themes/Templates/External/Client/[Owner].Theme.[Theme].Client.csproj b/Oqtane.Server/wwwroot/Themes/Templates/External/Client/[Owner].Theme.[Theme].Client.csproj index a25114e5..a40bfb11 100644 --- a/Oqtane.Server/wwwroot/Themes/Templates/External/Client/[Owner].Theme.[Theme].Client.csproj +++ b/Oqtane.Server/wwwroot/Themes/Templates/External/Client/[Owner].Theme.[Theme].Client.csproj @@ -13,9 +13,9 @@ - - - + + + diff --git a/Oqtane.Shared/Oqtane.Shared.csproj b/Oqtane.Shared/Oqtane.Shared.csproj index ff45903a..c3854210 100644 --- a/Oqtane.Shared/Oqtane.Shared.csproj +++ b/Oqtane.Shared/Oqtane.Shared.csproj @@ -19,11 +19,11 @@ - - - + + + - + From 899bf22e15ac617acdc9cd628582d7d16a1ae96a Mon Sep 17 00:00:00 2001 From: sbwalker Date: Tue, 12 Nov 2024 15:50:13 -0500 Subject: [PATCH 32/38] update PostgreSQL provider to official .NET 9 release --- Oqtane.Database.PostgreSQL/Oqtane.Database.PostgreSQL.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Oqtane.Database.PostgreSQL/Oqtane.Database.PostgreSQL.csproj b/Oqtane.Database.PostgreSQL/Oqtane.Database.PostgreSQL.csproj index 79ed9b5c..d440daed 100644 --- a/Oqtane.Database.PostgreSQL/Oqtane.Database.PostgreSQL.csproj +++ b/Oqtane.Database.PostgreSQL/Oqtane.Database.PostgreSQL.csproj @@ -34,7 +34,7 @@ - + From 4cf4e0eabdfc5380e2a957bb5190cfda1a1ef430 Mon Sep 17 00:00:00 2001 From: Ben Date: Wed, 13 Nov 2024 23:06:43 +0800 Subject: [PATCH 33/38] add reference to Microsoft.EntityFrameworkCore package. --- Oqtane.Database.PostgreSQL/Oqtane.Database.PostgreSQL.csproj | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Oqtane.Database.PostgreSQL/Oqtane.Database.PostgreSQL.csproj b/Oqtane.Database.PostgreSQL/Oqtane.Database.PostgreSQL.csproj index d440daed..09f36744 100644 --- a/Oqtane.Database.PostgreSQL/Oqtane.Database.PostgreSQL.csproj +++ b/Oqtane.Database.PostgreSQL/Oqtane.Database.PostgreSQL.csproj @@ -25,15 +25,16 @@ - 1701;1702;EF1001;AD0001 + 1701;1702;EF1001;AD0001;NU1608 - 1701;1702;EF1001;AD0001 + 1701;1702;EF1001;AD0001;NU1608 + From 0202bf60e532dafe7df10a114efa1d1f240f5aea Mon Sep 17 00:00:00 2001 From: sbwalker Date: Wed, 13 Nov 2024 13:51:54 -0500 Subject: [PATCH 34/38] adjust gitignore to exclude wwwroot/_content subfolders --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 69863764..04ce32b7 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,9 @@ Oqtane.Server/Packages Oqtane.Server/wwwroot/Content Oqtane.Server/wwwroot/Packages/*.log +Oqtane.Server/wwwroot/_content/* +!Oqtane.Server/wwwroot/_content/Placeholder.txt + Oqtane.Server/wwwroot/Modules/* !Oqtane.Server/wwwroot/Modules/Oqtane.Modules.* !Oqtane.Server/wwwroot/Modules/Templates From 574164081b65d883b1c06c0aa55a6389823170c4 Mon Sep 17 00:00:00 2001 From: sbwalker Date: Wed, 13 Nov 2024 14:14:35 -0500 Subject: [PATCH 35/38] exclude wwwroot/_content from official release build --- Oqtane.Package/release.cmd | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Oqtane.Package/release.cmd b/Oqtane.Package/release.cmd index 2c9fde54..3aa117db 100644 --- a/Oqtane.Package/release.cmd +++ b/Oqtane.Package/release.cmd @@ -12,6 +12,14 @@ dotnet publish ..\Oqtane.Server\Oqtane.Server.csproj /p:Configuration=Release del /F/Q/S "..\Oqtane.Server\bin\Release\net9.0\publish\wwwroot\Content" > NUL rmdir /Q/S "..\Oqtane.Server\bin\Release\net9.0\publish\wwwroot\Content" setlocal ENABLEDELAYEDEXPANSION +set retain=Placeholder.txt +for /D %%i in ("..\Oqtane.Server\bin\Release\net9.0\publish\wwwroot\_content\*") do ( +set /A found=0 +for %%j in (%retain%) do ( +if "%%~nxi" == "%%j" set /A found=1 +) +if not !found! == 1 rmdir /Q/S "%%i" +) set retain=Oqtane.Modules.Admin.Login,Oqtane.Modules.HtmlText for /D %%i in ("..\Oqtane.Server\bin\Release\net9.0\publish\wwwroot\Modules\*") do ( set /A found=0 From 27120d6cc912af129c1a09d0175b0aee44d0be6f Mon Sep 17 00:00:00 2001 From: sbwalker Date: Wed, 13 Nov 2024 20:37:10 -0500 Subject: [PATCH 36/38] modifications to get .NET MAUI working on .NET 9 official release --- Oqtane.Maui/Oqtane.Maui.csproj | 4 +++- Oqtane.Maui/Properties/launchSettings.json | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Oqtane.Maui/Oqtane.Maui.csproj b/Oqtane.Maui/Oqtane.Maui.csproj index 1cbd246f..32d34828 100644 --- a/Oqtane.Maui/Oqtane.Maui.csproj +++ b/Oqtane.Maui/Oqtane.Maui.csproj @@ -28,12 +28,14 @@ com.oqtane.maui - 0E29FC31-1B83-48ED-B6E0-9F3C67B775D4 6.0.0 1 + + None + 15.0 15.0 24.0 diff --git a/Oqtane.Maui/Properties/launchSettings.json b/Oqtane.Maui/Properties/launchSettings.json index edf8aadc..4f857936 100644 --- a/Oqtane.Maui/Properties/launchSettings.json +++ b/Oqtane.Maui/Properties/launchSettings.json @@ -1,7 +1,7 @@ { "profiles": { "Windows Machine": { - "commandName": "MsixPackage", + "commandName": "Project", "nativeDebugging": false } } From 92aa2236c0eb3fe58d1370ff5cdc5cb86a9f31ef Mon Sep 17 00:00:00 2001 From: Leigh Pointer Date: Thu, 14 Nov 2024 09:16:55 +0100 Subject: [PATCH 37/38] Swashbuckle.AspNetCore updated to 7.0 --- Oqtane.Server/Oqtane.Server.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Oqtane.Server/Oqtane.Server.csproj b/Oqtane.Server/Oqtane.Server.csproj index e4b5a55f..993d40e2 100644 --- a/Oqtane.Server/Oqtane.Server.csproj +++ b/Oqtane.Server/Oqtane.Server.csproj @@ -47,7 +47,7 @@ - + From aaaf5683a5e7ba567b6e0f6afb8346ae740ae010 Mon Sep 17 00:00:00 2001 From: Leigh Pointer Date: Thu, 14 Nov 2024 09:50:05 +0100 Subject: [PATCH 38/38] Fix: "Search_Enabled" was being saved as Private so unauthorized users can not access this value. --- Oqtane.Client/Modules/Admin/Search/Index.razor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Oqtane.Client/Modules/Admin/Search/Index.razor b/Oqtane.Client/Modules/Admin/Search/Index.razor index 57caa1aa..ee47feea 100644 --- a/Oqtane.Client/Modules/Admin/Search/Index.razor +++ b/Oqtane.Client/Modules/Admin/Search/Index.razor @@ -85,7 +85,7 @@ { var settings = await SettingService.GetSiteSettingsAsync(PageState.Site.SiteId); settings = SettingService.SetSetting(settings, "Search_SearchProvider", _searchProvider); - settings = SettingService.SetSetting(settings, "Search_Enabled", _enabled, true); + settings = SettingService.SetSetting(settings, "Search_Enabled", _enabled); settings = SettingService.SetSetting(settings, "Search_LastIndexedOn", _lastIndexedOn, true); settings = SettingService.SetSetting(settings, "Search_IgnorePages", _ignorePages, true); settings = SettingService.SetSetting(settings, "Search_IgnoreEntities", _ignoreEntities, true);