From 38f323f74a40777027fb74cc72c52747920ecca9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Climent?= Date: Sat, 7 Jun 2025 23:46:00 +0200 Subject: [PATCH 01/10] Update .deepsource.toml --- .deepsource.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.deepsource.toml b/.deepsource.toml index 2a4202f4c7..227ede7321 100644 --- a/.deepsource.toml +++ b/.deepsource.toml @@ -62,4 +62,4 @@ enabled = false # Disables standardjs transformer [[transformers]] name = "prettier" -enabled = false # Disables prettier transformer +enabled = false # Disables prettier transformer \ No newline at end of file From d94b167e859044e1f961672de6d564844d42a058 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Climent?= Date: Sun, 8 Jun 2025 22:36:27 +0200 Subject: [PATCH 02/10] Add [yet untested] code skeleton for secure settings --- cli-arguments.md | 5 +- .../SecureSettings.cs | 90 ++++++++++++++ .../UniGetUI.Core.SecureSettings.csproj | 10 ++ src/UniGetUI.sln | 7 ++ src/UniGetUI/CLIHandler.cs | 117 +++++++++++++++++- src/UniGetUI/EntryPoint.cs | 20 +++ src/UniGetUI/UniGetUI.csproj | 1 + 7 files changed, 242 insertions(+), 8 deletions(-) create mode 100644 src/UniGetUI.Core.SecureSettings/SecureSettings.cs create mode 100644 src/UniGetUI.Core.SecureSettings/UniGetUI.Core.SecureSettings.csproj diff --git a/cli-arguments.md b/cli-arguments.md index 95a9988560..0721efa7e7 100644 --- a/cli-arguments.md +++ b/cli-arguments.md @@ -12,10 +12,11 @@ | `--help` | Opens this page | 3.2.0+ | | `--import-settings file` | Imports UniGetUI settings from json file _file_. The file must exist. The old settings will be lost* | 3.2.0+ | | `--export-settings file` | Exports UniGetUI settings to json file _file_. The file will be created or overwritten* | 3.2.0+ | -| `--enable-setting key` | Enables the boolean setting _key_* | 3.2.0+ | -| `--disable-setting key` | Disables the boolean setting _key_* | 3.2.0+ | +| `--[enable\|disable]-setting key` | Enables/disables the boolean setting _key_* | 3.2.0+ | | `--set-setting-value key value` | Sets the value _value_ to the non-boolean setting _key_. To clear a non-boolean setting, `--disable-setting` can be used* | 3.2.0+ | | `--no-corrupt-dialog` | Will show a verbose error message (the error report) instead of a simplified message dialog | 3.2.1+ | +| `--[enable\|disable]-secure-setting-for-user username key` | Enables/disables the given secure setting for the given username. Requires administrator rights. | 3.2.1+ | +| `--[enable\|disable]-secure-setting key` | Enables/disables the given secure setting for current user. This will generate a UAC prompt | 3.2.1+ | \*After modifying the settings, you must ensure that any running instance of UniGetUI is restarted for the changes to take effect diff --git a/src/UniGetUI.Core.SecureSettings/SecureSettings.cs b/src/UniGetUI.Core.SecureSettings/SecureSettings.cs new file mode 100644 index 0000000000..01db9654e9 --- /dev/null +++ b/src/UniGetUI.Core.SecureSettings/SecureSettings.cs @@ -0,0 +1,90 @@ +using System.Diagnostics; +using UniGetUI.Core.Data; +using UniGetUI.Core.Tools; + +namespace UniGetUI.Core.SettingsEngine.SecureSettings; + +public static class SecureSettings +{ + public static class Args + { + public const string ENABLE_FOR_USER = "--enable-secure-setting-for-user"; + public const string DISABLE_FOR_USER = "--disable-secure-setting-for-user"; + } + + public static bool Get(string setting) + { + string purifiedUser = CoreTools.MakeValidFileName(Environment.UserName); + string purifiedSetting = CoreTools.MakeValidFileName(setting); + + var appData = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles); + var settingsLocation = Path.Join(appData, "UniGetUI\\SecureSettings", purifiedUser); + var settingFile = Path.Join(settingsLocation, purifiedSetting); + + if (!Directory.Exists(settingsLocation)) + return false; + + return File.Exists(settingFile); + } + + public static async Task TrySet(string setting, bool enabled) + { + string purifiedUser = CoreTools.MakeValidFileName(Environment.UserName); + string purifiedSetting = CoreTools.MakeValidFileName(setting); + + using Process p = new Process(); + p.StartInfo = new() + { + UseShellExecute = false, + CreateNoWindow = true, + FileName = CoreData.UniGetUIExecutableFile, + ArgumentList = + { + enabled? Args.ENABLE_FOR_USER: Args.DISABLE_FOR_USER, + purifiedUser, + purifiedSetting + } + }; + + p.Start(); + await p.WaitForExitAsync(); + return p.ExitCode is 0; + } + + public static int ApplyForUser(string username, string setting, bool enable) + { + try + { + string purifiedUser = CoreTools.MakeValidFileName(username); + string purifiedSetting = CoreTools.MakeValidFileName(setting); + + var appData = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData); + var settingsLocation = Path.Join(appData, "UniGetUI\\SecureSettings", purifiedUser); + var settingFile = Path.Join(settingsLocation, purifiedSetting); + + if (!Directory.Exists(settingsLocation)) + { + Directory.CreateDirectory(settingsLocation); + } + + if (enable) + { + File.WriteAllText(settingFile, ""); + } + else + { + if (File.Exists(settingFile)) + { + File.Delete(settingFile); + } + } + + return 0; + } + catch (Exception ex) + { + Console.WriteLine(ex); + return -1; + } + } +} diff --git a/src/UniGetUI.Core.SecureSettings/UniGetUI.Core.SecureSettings.csproj b/src/UniGetUI.Core.SecureSettings/UniGetUI.Core.SecureSettings.csproj new file mode 100644 index 0000000000..4483561c9f --- /dev/null +++ b/src/UniGetUI.Core.SecureSettings/UniGetUI.Core.SecureSettings.csproj @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/UniGetUI.sln b/src/UniGetUI.sln index 7324d653bb..d71e0676e3 100644 --- a/src/UniGetUI.sln +++ b/src/UniGetUI.sln @@ -105,6 +105,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{015B44EE EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UniGetUI.PackageEngine.Serializable.Tests", "UniGetUI.PackageEngine.Serializable.Tests\UniGetUI.PackageEngine.Serializable.Tests.csproj", "{F1610A61-5444-4C11-9447-13CCA327887E}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UniGetUI.Core.SecureSettings", "UniGetUI.Core.SecureSettings\UniGetUI.Core.SecureSettings.csproj", "{B0E59327-933E-4DB0-BD2D-FB16EB9B4194}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -271,6 +273,10 @@ Global {F1610A61-5444-4C11-9447-13CCA327887E}.Debug|x64.Build.0 = Debug|x64 {F1610A61-5444-4C11-9447-13CCA327887E}.Release|x64.ActiveCfg = Release|x64 {F1610A61-5444-4C11-9447-13CCA327887E}.Release|x64.Build.0 = Release|x64 + {B0E59327-933E-4DB0-BD2D-FB16EB9B4194}.Debug|x64.ActiveCfg = Debug|x64 + {B0E59327-933E-4DB0-BD2D-FB16EB9B4194}.Debug|x64.Build.0 = Debug|x64 + {B0E59327-933E-4DB0-BD2D-FB16EB9B4194}.Release|x64.ActiveCfg = Release|x64 + {B0E59327-933E-4DB0-BD2D-FB16EB9B4194}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -319,6 +325,7 @@ Global {3C8BF564-B4B5-44A7-9D8C-102C2F820EAF} = {8CF74C87-534F-4017-A4ED-F2918025E31A} {015B44EE-32AE-4105-9016-49140743CAF9} = {7940E867-EEBA-4AFD-9904-1536F003239C} {F1610A61-5444-4C11-9447-13CCA327887E} = {015B44EE-32AE-4105-9016-49140743CAF9} + {B0E59327-933E-4DB0-BD2D-FB16EB9B4194} = {E05D1183-D360-4AFE-8968-314A34FAD3B2} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {D044BB14-0B37-47E5-A579-8B30FCBA1F9F} diff --git a/src/UniGetUI/CLIHandler.cs b/src/UniGetUI/CLIHandler.cs index 797e9316a8..3a170c29aa 100644 --- a/src/UniGetUI/CLIHandler.cs +++ b/src/UniGetUI/CLIHandler.cs @@ -1,5 +1,6 @@ using UniGetUI.Core.Logging; using UniGetUI.Core.SettingsEngine; +using UniGetUI.Core.SettingsEngine.SecureSettings; namespace UniGetUI; @@ -19,10 +20,16 @@ public static class CLIHandler public const string DISABLE_SETTING = "--disable-setting"; public const string SET_SETTING_VAL = "--set-setting-value"; + public const string ENABLE_SECURE_SETTING = "--enable-secure-setting"; + public const string DISABLE_SECURE_SETTING = "--disable-secure-setting"; + public const string ENABLE_SECURE_SETTING_FOR_USER = SecureSettings.Args.ENABLE_FOR_USER; + public const string DISABLE_SECURE_SETTING_FOR_USER = SecureSettings.Args.DISABLE_FOR_USER; + private enum HRESULT { - SUCCESS = 0x00000000, + SUCCESS = 0, + STATUS_FAILED = -1, STATUS_INVALID_PARAMETER = -1073741811, STATUS_NO_SUCH_FILE = -1073741809, } @@ -48,7 +55,7 @@ public static int ImportSettings() if (filePos +1 >= args.Count) return (int)HRESULT.STATUS_INVALID_PARAMETER; // The file parameter does not exist (import settings requires "--import-settings file") - var file = args[filePos + 1].Replace("\"", "").Replace("\'", ""); + var file = args[filePos + 1].Trim('"').Trim('\''); if (!File.Exists(file)) return (int)HRESULT.STATUS_NO_SUCH_FILE; // The given file does not exist @@ -75,7 +82,7 @@ public static int ExportSettings() if (filePos +1 >= args.Count) return (int)HRESULT.STATUS_INVALID_PARAMETER; // The file parameter does not exist (export settings requires "--export-settings file") - var file = args[filePos + 1].Replace("\"", "").Replace("\'", ""); + var file = args[filePos + 1].Trim('"').Trim('\''); try { @@ -100,7 +107,7 @@ public static int EnableSetting() if (basePos +1 >= args.Count) return (int)HRESULT.STATUS_INVALID_PARAMETER; // The file parameter does not exist (export settings requires "--export-settings file") - var setting = args[basePos + 1].Replace("\"", "").Replace("\'", ""); + var setting = args[basePos + 1].Trim('"').Trim('\''); try { @@ -125,7 +132,7 @@ public static int DisableSetting() if (basePos +1 >= args.Count) return (int)HRESULT.STATUS_INVALID_PARAMETER; // The file parameter does not exist (export settings requires "--export-settings file") - var setting = args[basePos + 1].Replace("\"", "").Replace("\'", ""); + var setting = args[basePos + 1].Trim('"').Trim('\''); try { @@ -150,7 +157,7 @@ public static int SetSettingsValue() if (basePos +2 >= args.Count) return (int)HRESULT.STATUS_INVALID_PARAMETER; // The file parameter does not exist (export settings requires "--export-settings file") - var setting = args[basePos + 1].Replace("\"", "").Replace("\'", ""); + var setting = args[basePos + 1].Trim('"').Trim('\''); var value = args[basePos + 2]; try @@ -230,4 +237,102 @@ public static int UninstallUniGetUI() // There is currently no uninstall logic. However, this needs to be maintained, or otherwhise UniGetUI will launch on uninstall return 0; } + + public static int EnableSecureSetting() + { + var args = Environment.GetCommandLineArgs().ToList(); + + var basePos = args.IndexOf(ENABLE_SECURE_SETTING); + if (basePos < 0) + return (int)HRESULT.STATUS_INVALID_PARAMETER; // The base paramater was not found + + if (basePos +1 >= args.Count) + return (int)HRESULT.STATUS_INVALID_PARAMETER; // The file parameter does not exist (export settings requires "--export-settings file") + + var setting = args[basePos + 1].Trim('"').Trim('\''); + + try + { + bool success = SecureSettings.TrySet(setting, true).GetAwaiter().GetResult(); + if (!success) return (int)HRESULT.STATUS_FAILED; + else return (int)HRESULT.SUCCESS; + } + catch (Exception ex) + { + return ex.HResult; + } + } + + public static int DisableSecureSetting() + { + var args = Environment.GetCommandLineArgs().ToList(); + + var basePos = args.IndexOf(DISABLE_SECURE_SETTING); + if (basePos < 0) + return (int)HRESULT.STATUS_INVALID_PARAMETER; // The base paramater was not found + + if (basePos +1 >= args.Count) + return (int)HRESULT.STATUS_INVALID_PARAMETER; // The first positional argument does not exist + + var setting = args[basePos + 1].Trim('"').Trim('\''); + + try + { + bool success = SecureSettings.TrySet(setting, false).GetAwaiter().GetResult(); + if (!success) return (int)HRESULT.STATUS_FAILED; + else return (int)HRESULT.SUCCESS; + } + catch (Exception ex) + { + return ex.HResult; + } + } + + public static int EnableSecureSettingForUser() + { + var args = Environment.GetCommandLineArgs().ToList(); + + var basePos = args.IndexOf(ENABLE_SECURE_SETTING); + if (basePos < 0) + return (int)HRESULT.STATUS_INVALID_PARAMETER; // The base paramater was not found + + if (basePos +2 >= args.Count) + return (int)HRESULT.STATUS_INVALID_PARAMETER; // The required parameters do not exist + + var user = args[basePos + 1].Trim('"').Trim('\''); + var setting = args[basePos + 2].Trim('"').Trim('\''); + + try + { + return SecureSettings.ApplyForUser(user, setting, true); + } + catch (Exception ex) + { + return ex.HResult; + } + } + + public static int DisableSecureSettingForUser() + { + var args = Environment.GetCommandLineArgs().ToList(); + + var basePos = args.IndexOf(ENABLE_SECURE_SETTING); + if (basePos < 0) + return (int)HRESULT.STATUS_INVALID_PARAMETER; // The base paramater was not found + + if (basePos +2 >= args.Count) + return (int)HRESULT.STATUS_INVALID_PARAMETER; // The required parameters do not exist + + var user = args[basePos + 1].Trim('"').Trim('\''); + var setting = args[basePos + 2].Trim('"').Trim('\''); + + try + { + return SecureSettings.ApplyForUser(user, setting, false); + } + catch (Exception ex) + { + return ex.HResult; + } + } } diff --git a/src/UniGetUI/EntryPoint.cs b/src/UniGetUI/EntryPoint.cs index d0ef2999f4..20514ed893 100644 --- a/src/UniGetUI/EntryPoint.cs +++ b/src/UniGetUI/EntryPoint.cs @@ -55,6 +55,26 @@ private static void Main(string[] args) int ret = CLIHandler.SetSettingsValue(); Environment.Exit(ret); } + else if (args.Contains(CLIHandler.ENABLE_SECURE_SETTING)) + { + int ret = CLIHandler.EnableSecureSetting(); + Environment.Exit(ret); + } + else if (args.Contains(CLIHandler.DISABLE_SECURE_SETTING)) + { + int ret = CLIHandler.DisableSecureSetting(); + Environment.Exit(ret); + } + else if (args.Contains(CLIHandler.ENABLE_SECURE_SETTING_FOR_USER)) + { + int ret = CLIHandler.EnableSecureSettingForUser(); + Environment.Exit(ret); + } + else if (args.Contains(CLIHandler.DISABLE_SECURE_SETTING_FOR_USER)) + { + int ret = CLIHandler.DisableSecureSettingForUser(); + Environment.Exit(ret); + } else { CoreData.WasDaemon = CoreData.IsDaemon = args.Contains(CLIHandler.DAEMON); diff --git a/src/UniGetUI/UniGetUI.csproj b/src/UniGetUI/UniGetUI.csproj index 6856170f51..9a3c1c3188 100644 --- a/src/UniGetUI/UniGetUI.csproj +++ b/src/UniGetUI/UniGetUI.csproj @@ -270,6 +270,7 @@ + From 1894ab8f690f2c9d769157a31839d5556ffa57ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Climent?= Date: Mon, 9 Jun 2025 20:44:47 +0200 Subject: [PATCH 03/10] Add working example toggle with UAC prompt --- .../SecureSettings.cs | 5 +- .../UniGetUI.Core.SecureSettings.csproj | 1 - src/UniGetUI/CLIHandler.cs | 4 +- .../SettingsWidgets/SecureCheckboxCard.cs | 96 +++++++++++++++++++ .../GeneralPages/Experimental.xaml | 9 ++ src/UniGetUI/Properties/launchSettings.json | 3 +- 6 files changed, 112 insertions(+), 6 deletions(-) create mode 100644 src/UniGetUI/Controls/SettingsWidgets/SecureCheckboxCard.cs diff --git a/src/UniGetUI.Core.SecureSettings/SecureSettings.cs b/src/UniGetUI.Core.SecureSettings/SecureSettings.cs index 01db9654e9..87d55e2713 100644 --- a/src/UniGetUI.Core.SecureSettings/SecureSettings.cs +++ b/src/UniGetUI.Core.SecureSettings/SecureSettings.cs @@ -35,9 +35,10 @@ public static async Task TrySet(string setting, bool enabled) using Process p = new Process(); p.StartInfo = new() { - UseShellExecute = false, + UseShellExecute = true, CreateNoWindow = true, FileName = CoreData.UniGetUIExecutableFile, + Verb = "runas", ArgumentList = { enabled? Args.ENABLE_FOR_USER: Args.DISABLE_FOR_USER, @@ -58,7 +59,7 @@ public static int ApplyForUser(string username, string setting, bool enable) string purifiedUser = CoreTools.MakeValidFileName(username); string purifiedSetting = CoreTools.MakeValidFileName(setting); - var appData = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData); + var appData = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles); var settingsLocation = Path.Join(appData, "UniGetUI\\SecureSettings", purifiedUser); var settingFile = Path.Join(settingsLocation, purifiedSetting); diff --git a/src/UniGetUI.Core.SecureSettings/UniGetUI.Core.SecureSettings.csproj b/src/UniGetUI.Core.SecureSettings/UniGetUI.Core.SecureSettings.csproj index 4483561c9f..704c7f08fb 100644 --- a/src/UniGetUI.Core.SecureSettings/UniGetUI.Core.SecureSettings.csproj +++ b/src/UniGetUI.Core.SecureSettings/UniGetUI.Core.SecureSettings.csproj @@ -1,6 +1,5 @@ - diff --git a/src/UniGetUI/CLIHandler.cs b/src/UniGetUI/CLIHandler.cs index 3a170c29aa..d917e4e259 100644 --- a/src/UniGetUI/CLIHandler.cs +++ b/src/UniGetUI/CLIHandler.cs @@ -292,7 +292,7 @@ public static int EnableSecureSettingForUser() { var args = Environment.GetCommandLineArgs().ToList(); - var basePos = args.IndexOf(ENABLE_SECURE_SETTING); + var basePos = args.IndexOf(ENABLE_SECURE_SETTING_FOR_USER); if (basePos < 0) return (int)HRESULT.STATUS_INVALID_PARAMETER; // The base paramater was not found @@ -316,7 +316,7 @@ public static int DisableSecureSettingForUser() { var args = Environment.GetCommandLineArgs().ToList(); - var basePos = args.IndexOf(ENABLE_SECURE_SETTING); + var basePos = args.IndexOf(DISABLE_SECURE_SETTING_FOR_USER); if (basePos < 0) return (int)HRESULT.STATUS_INVALID_PARAMETER; // The base paramater was not found diff --git a/src/UniGetUI/Controls/SettingsWidgets/SecureCheckboxCard.cs b/src/UniGetUI/Controls/SettingsWidgets/SecureCheckboxCard.cs new file mode 100644 index 0000000000..701ecb2089 --- /dev/null +++ b/src/UniGetUI/Controls/SettingsWidgets/SecureCheckboxCard.cs @@ -0,0 +1,96 @@ +using CommunityToolkit.WinUI.Controls; +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Controls; +using UniGetUI.Core.Logging; +using UniGetUI.Core.SettingsEngine.SecureSettings; +using UniGetUI.Core.Tools; + +// To learn more about WinUI, the WinUI project structure, +// and more about our project templates, see: http://aka.ms/winui-project-info. + +namespace UniGetUI.Interface.Widgets +{ + public partial class SecureCheckboxCard : SettingsCard + { + public ToggleSwitch _checkbox; + public TextBlock _textblock; + public ProgressRing _loading; + protected bool IS_INVERTED; + + protected string setting_name = ""; + public virtual string SettingName + { + set + { + setting_name = value; + IS_INVERTED = value.StartsWith("Disable"); + _checkbox.IsOn = SecureSettings.Get(setting_name) ^ IS_INVERTED ^ ForceInversion; + _textblock.Opacity = _checkbox.IsOn ? 1 : 0.7; + } + } + + public bool ForceInversion { get; set; } + + public bool Checked + { + get => _checkbox.IsOn; + } + public virtual event EventHandler? StateChanged; + + public string Text + { + set => _textblock.Text = CoreTools.Translate(value); + } + + public SecureCheckboxCard() + { + _checkbox = new ToggleSwitch() + { + Margin = new Thickness(0, 0, 8, 0) + }; + + _loading = new ProgressRing() { IsIndeterminate = true, Visibility = Visibility.Collapsed}; + _textblock = new TextBlock() + { + VerticalAlignment = VerticalAlignment.Center, + Margin = new Thickness(0, 0, 0, 0), + TextWrapping = TextWrapping.Wrap + }; + IS_INVERTED = false; + Content = new StackPanel() + { + Spacing = 4, + Orientation = Orientation.Horizontal, + Children = { _loading, _checkbox }, + }; + Header = _textblock; + + _checkbox.HorizontalAlignment = HorizontalAlignment.Stretch; + _checkbox.Toggled += (s, e) => _ = _checkbox_Toggled(); + } + protected virtual async Task _checkbox_Toggled() + { + try + { + if (_checkbox.IsEnabled is false) + return; + + _loading.Visibility = Visibility.Visible; + _checkbox.IsEnabled = false; + StateChanged?.Invoke(this, EventArgs.Empty); + await SecureSettings.TrySet(setting_name, _checkbox.IsOn ^ IS_INVERTED ^ ForceInversion); + _textblock.Opacity = _checkbox.IsOn ? 1 : 0.7; + _checkbox.IsOn = SecureSettings.Get(setting_name); + _loading.Visibility = Visibility.Collapsed; + _checkbox.IsEnabled = true; + } + catch (Exception ex) + { + Logger.Warn(ex); + _checkbox.IsOn = SecureSettings.Get(setting_name); + _loading.Visibility = Visibility.Collapsed; + _checkbox.IsEnabled = true; + } + } + } +} diff --git a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Experimental.xaml b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Experimental.xaml index d49e1bc3d7..3be338fafe 100644 --- a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Experimental.xaml +++ b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Experimental.xaml @@ -91,6 +91,15 @@ CornerRadius="8" SettingName="DisableDMWThreadOptimizations" Text="Enable background CPU Usage optimizations (see Pull Request #3278)" /> + + + + + diff --git a/src/UniGetUI/Properties/launchSettings.json b/src/UniGetUI/Properties/launchSettings.json index 4c8375a637..7108a3ce55 100644 --- a/src/UniGetUI/Properties/launchSettings.json +++ b/src/UniGetUI/Properties/launchSettings.json @@ -4,7 +4,8 @@ "commandName": "MsixPackage" }, "UniGetUI (Unpackaged)": { - "commandName": "Project" + "commandName": "Project", + "commandLineArgs": "" } } } From 64767d470ad3c1ee8c067ac22413cca36810d048 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Climent?= Date: Mon, 9 Jun 2025 22:44:57 +0200 Subject: [PATCH 04/10] little fix --- src/UniGetUI/Controls/SettingsWidgets/SecureCheckboxCard.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/UniGetUI/Controls/SettingsWidgets/SecureCheckboxCard.cs b/src/UniGetUI/Controls/SettingsWidgets/SecureCheckboxCard.cs index 701ecb2089..0b87345536 100644 --- a/src/UniGetUI/Controls/SettingsWidgets/SecureCheckboxCard.cs +++ b/src/UniGetUI/Controls/SettingsWidgets/SecureCheckboxCard.cs @@ -22,10 +22,12 @@ public virtual string SettingName { set { + _checkbox.IsEnabled = false; setting_name = value; IS_INVERTED = value.StartsWith("Disable"); _checkbox.IsOn = SecureSettings.Get(setting_name) ^ IS_INVERTED ^ ForceInversion; _textblock.Opacity = _checkbox.IsOn ? 1 : 0.7; + _checkbox.IsEnabled = true; } } From 550c1cec91cc971a910ff151d7e2ad6dc906fe5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Climent?= Date: Fri, 13 Jun 2025 18:52:37 +0200 Subject: [PATCH 05/10] Add new "Dangerous settings" settings section, add more things to SecureSettingsCheckbox --- .../SettingsWidgets/SecureCheckboxCard.cs | 32 +++++++++++-- .../GeneralPages/Administrator.xaml | 7 +++ .../GeneralPages/Administrator.xaml.cs | 9 ++++ .../GeneralPages/SettingsHomepage.xaml | 47 ++++++++++++------- .../GeneralPages/SettingsHomepage.xaml.cs | 2 +- .../SettingsPages/SettingsBasePage.xaml.cs | 4 ++ 6 files changed, 80 insertions(+), 21 deletions(-) diff --git a/src/UniGetUI/Controls/SettingsWidgets/SecureCheckboxCard.cs b/src/UniGetUI/Controls/SettingsWidgets/SecureCheckboxCard.cs index 0b87345536..58f12a7919 100644 --- a/src/UniGetUI/Controls/SettingsWidgets/SecureCheckboxCard.cs +++ b/src/UniGetUI/Controls/SettingsWidgets/SecureCheckboxCard.cs @@ -1,6 +1,7 @@ using CommunityToolkit.WinUI.Controls; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; +using Microsoft.UI.Xaml.Media; using UniGetUI.Core.Logging; using UniGetUI.Core.SettingsEngine.SecureSettings; using UniGetUI.Core.Tools; @@ -14,6 +15,7 @@ public partial class SecureCheckboxCard : SettingsCard { public ToggleSwitch _checkbox; public TextBlock _textblock; + public TextBlock _warningBlock; public ProgressRing _loading; protected bool IS_INVERTED; @@ -44,6 +46,15 @@ public string Text set => _textblock.Text = CoreTools.Translate(value); } + public string WarningText + { + set + { + _warningBlock.Text = CoreTools.Translate(value); + _warningBlock.Visibility = value.Any() ? Visibility.Visible : Visibility.Collapsed; + } + } + public SecureCheckboxCard() { _checkbox = new ToggleSwitch() @@ -58,6 +69,15 @@ public SecureCheckboxCard() Margin = new Thickness(0, 0, 0, 0), TextWrapping = TextWrapping.Wrap }; + _warningBlock = new TextBlock() + { + VerticalAlignment = VerticalAlignment.Center, + Margin = new Thickness(0, 0, 0, 0), + TextWrapping = TextWrapping.Wrap, + Foreground = (SolidColorBrush)Application.Current.Resources["SystemControlErrorTextForegroundBrush"], + FontSize = 12, + Visibility = Visibility.Collapsed, + }; IS_INVERTED = false; Content = new StackPanel() { @@ -65,7 +85,13 @@ public SecureCheckboxCard() Orientation = Orientation.Horizontal, Children = { _loading, _checkbox }, }; - Header = _textblock; + //Header = _textblock; + Header = new StackPanel() + { + Spacing = 4, + Orientation = Orientation.Vertical, + Children = { _textblock, _warningBlock } + }; _checkbox.HorizontalAlignment = HorizontalAlignment.Stretch; _checkbox.Toggled += (s, e) => _ = _checkbox_Toggled(); @@ -82,14 +108,14 @@ protected virtual async Task _checkbox_Toggled() StateChanged?.Invoke(this, EventArgs.Empty); await SecureSettings.TrySet(setting_name, _checkbox.IsOn ^ IS_INVERTED ^ ForceInversion); _textblock.Opacity = _checkbox.IsOn ? 1 : 0.7; - _checkbox.IsOn = SecureSettings.Get(setting_name); + _checkbox.IsOn = SecureSettings.Get(setting_name) ^ IS_INVERTED ^ ForceInversion; _loading.Visibility = Visibility.Collapsed; _checkbox.IsEnabled = true; } catch (Exception ex) { Logger.Warn(ex); - _checkbox.IsOn = SecureSettings.Get(setting_name); + _checkbox.IsOn = SecureSettings.Get(setting_name) ^ IS_INVERTED ^ ForceInversion; _loading.Visibility = Visibility.Collapsed; _checkbox.IsEnabled = true; } diff --git a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Administrator.xaml b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Administrator.xaml index a0d931e0aa..76fd7963cf 100644 --- a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Administrator.xaml +++ b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Administrator.xaml @@ -25,6 +25,13 @@ VerticalContentAlignment="Center"> + + true; diff --git a/src/UniGetUI/Pages/SettingsPages/GeneralPages/SettingsHomepage.xaml b/src/UniGetUI/Pages/SettingsPages/GeneralPages/SettingsHomepage.xaml index d8407f0759..92c4cf3935 100644 --- a/src/UniGetUI/Pages/SettingsPages/GeneralPages/SettingsHomepage.xaml +++ b/src/UniGetUI/Pages/SettingsPages/GeneralPages/SettingsHomepage.xaml @@ -57,14 +57,13 @@ UnderText="Show notifications on different events" /> - + Icon="uac" + Text="Administrator rights and other dangerous settings" + UnderText="Reduce UAC prompts, elevate installations by default, unlock certain dangerous features, etc." /> @@ -88,32 +87,46 @@ + Icon="disk" + Text="Package backup" + UnderText="Automatically save a list of all your installed packages to easily restore them." /> + + Text="Package manager preferences" + UnderText="Enable and disable package managers, change default install options, etc."> - + + + + + + + diff --git a/src/UniGetUI/Pages/SettingsPages/GeneralPages/SettingsHomepage.xaml.cs b/src/UniGetUI/Pages/SettingsPages/GeneralPages/SettingsHomepage.xaml.cs index c67633179f..93b02aad7f 100644 --- a/src/UniGetUI/Pages/SettingsPages/GeneralPages/SettingsHomepage.xaml.cs +++ b/src/UniGetUI/Pages/SettingsPages/GeneralPages/SettingsHomepage.xaml.cs @@ -33,6 +33,6 @@ public SettingsHomepage() public void Operations(object s, RoutedEventArgs e) => NavigationRequested?.Invoke(this, typeof(Operations)); public void Startup(object s, RoutedEventArgs e) => NavigationRequested?.Invoke(this, typeof(Updates)); private void Internet(object sender, RoutedEventArgs e) => NavigationRequested?.Invoke(this, typeof(Internet)); - + private void ManagersShortcut(object sender, RoutedEventArgs e) => NavigationRequested?.Invoke(this, typeof(ManagersHomepage)); } } diff --git a/src/UniGetUI/Pages/SettingsPages/SettingsBasePage.xaml.cs b/src/UniGetUI/Pages/SettingsPages/SettingsBasePage.xaml.cs index 81f42b1356..17f093a3e4 100644 --- a/src/UniGetUI/Pages/SettingsPages/SettingsBasePage.xaml.cs +++ b/src/UniGetUI/Pages/SettingsPages/SettingsBasePage.xaml.cs @@ -82,6 +82,10 @@ private void Page_RestartRequired(object? sender, EventArgs e) private void Page_NavigationRequested(object? sender, Type e) { + if(e == typeof(ManagersHomepage)) + { + MainApp.Instance.MainWindow.NavigationPage.NavigateTo(Interface.PageType.Managers); + } if(e.IsSubclassOf(typeof(PackageManager))) { MainNavigationFrame.Navigate(typeof(PackageManagerPage), e, new SlideNavigationTransitionInfo() { Effect = SlideNavigationTransitionEffect.FromRight} ); From c0fff6a1dd65710b03e63f2a01f3fada63974012 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Climent?= Date: Fri, 13 Jun 2025 19:03:35 +0200 Subject: [PATCH 06/10] Add new secure settings to the Admin UI --- .../SettingsWidgets/SecureCheckboxCard.cs | 10 ++++ .../GeneralPages/Administrator.xaml | 50 ++++++++++++++++++- 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/src/UniGetUI/Controls/SettingsWidgets/SecureCheckboxCard.cs b/src/UniGetUI/Controls/SettingsWidgets/SecureCheckboxCard.cs index 58f12a7919..cb15b53771 100644 --- a/src/UniGetUI/Controls/SettingsWidgets/SecureCheckboxCard.cs +++ b/src/UniGetUI/Controls/SettingsWidgets/SecureCheckboxCard.cs @@ -33,6 +33,16 @@ public virtual string SettingName } } + public new bool IsEnabled + { + set + { + base.IsEnabled = value; + _warningBlock.Opacity = value ? 1 : 0.2; + } + get => base.IsEnabled; + } + public bool ForceInversion { get; set; } public bool Checked diff --git a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Administrator.xaml b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Administrator.xaml index 76fd7963cf..0ef7051ca6 100644 --- a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Administrator.xaml +++ b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Administrator.xaml @@ -51,7 +51,55 @@ CornerRadius="0,0,8,8" SettingName="DoCacheAdminRights" StateChanged="RestartCache" - Text="Ask only once for administrator privileges (not recommended)" /> + Text="Ask only once for administrator privileges" /> + + + + + + + + + + + + From f1877bd94cf9ce2a6c23bc781b53b319e477e84d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Climent?= Date: Fri, 13 Jun 2025 23:32:15 +0200 Subject: [PATCH 07/10] Update Administrator.xaml.cs --- .../Pages/SettingsPages/GeneralPages/Administrator.xaml.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Administrator.xaml.cs b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Administrator.xaml.cs index 37cdee8f21..720fc13d08 100644 --- a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Administrator.xaml.cs +++ b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Administrator.xaml.cs @@ -24,7 +24,7 @@ public Administrator() WarningTitlebar.Title = CoreTools.Translate("Warning") + "!"; WarningTitlebar.Message = CoreTools.Translate("The following settings may pose a security risk, hence they are disabled by default.") + " " + - CoreTools.Translate("Enable the settings below only if you fully understand what they do, and the implications they may have.") + "\n\n" + + CoreTools.Translate("Enable the settings below if and only if you fully understand what they do, and the implications they may have.") + "\n\n" + CoreTools.Translate("The settings will list, in their descriptions, the potential security issues they may have.") + " "; // The following settings may pose a security risk, hence they are disabled by default. Enable them ONLY if you undertsand what you are doing. Some of those settings will show a UAC prompt before being enabled." From 6b049972efacf33e8c0aed21fee4fbac65786589 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Climent?= Date: Fri, 13 Jun 2025 23:34:06 +0200 Subject: [PATCH 08/10] remove test entry --- .../SettingsPages/GeneralPages/Experimental.xaml | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Experimental.xaml b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Experimental.xaml index 3be338fafe..56a60ca9f2 100644 --- a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Experimental.xaml +++ b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Experimental.xaml @@ -44,6 +44,7 @@ StateChanged="ShowRestartBanner" Text="Wait for the device to be connected to the internet before attempting to do tasks that require internet connectivity." /> + - + Text="Use installed GSudo instead of the bundled one" / + --> @@ -92,13 +95,6 @@ SettingName="DisableDMWThreadOptimizations" Text="Enable background CPU Usage optimizations (see Pull Request #3278)" /> - - - From e5a27ffb0bdcd9790171f510ab771ae9001cf37d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Climent?= Date: Sat, 14 Jun 2025 00:11:24 +0200 Subject: [PATCH 09/10] Block CLI parameters if they have not been enabled from Secure Settings --- .../SecureSettings.cs | 24 ++++++++++-- .../Packages/Classes/InstallOptionsFactory.cs | 37 ++++++++++++++++--- .../UniGetUI.PackageEngine.Classes.csproj | 1 + .../InstallOptions.cs | 16 -------- .../Controls/SettingsWidgets/CheckboxCard.cs | 31 +++++++++++++++- .../InstallOptions_Package.xaml.cs | 8 ++-- .../GeneralPages/Administrator.xaml | 8 ++-- .../GeneralPages/Administrator.xaml.cs | 2 +- .../GeneralPages/Operations.xaml | 4 +- .../SettingsPages/GeneralPages/Updates.xaml | 6 +-- 10 files changed, 97 insertions(+), 40 deletions(-) diff --git a/src/UniGetUI.Core.SecureSettings/SecureSettings.cs b/src/UniGetUI.Core.SecureSettings/SecureSettings.cs index 87d55e2713..a7f784c194 100644 --- a/src/UniGetUI.Core.SecureSettings/SecureSettings.cs +++ b/src/UniGetUI.Core.SecureSettings/SecureSettings.cs @@ -6,6 +6,8 @@ namespace UniGetUI.Core.SettingsEngine.SecureSettings; public static class SecureSettings { + private static readonly Dictionary _cache = new(); + public static class Args { public const string ENABLE_FOR_USER = "--enable-secure-setting-for-user"; @@ -14,23 +16,35 @@ public static class Args public static bool Get(string setting) { - string purifiedUser = CoreTools.MakeValidFileName(Environment.UserName); string purifiedSetting = CoreTools.MakeValidFileName(setting); + if (_cache.TryGetValue(purifiedSetting, out var value)) + { + return value; + } + + string purifiedUser = CoreTools.MakeValidFileName(Environment.UserName); var appData = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles); var settingsLocation = Path.Join(appData, "UniGetUI\\SecureSettings", purifiedUser); var settingFile = Path.Join(settingsLocation, purifiedSetting); if (!Directory.Exists(settingsLocation)) + { + _cache[purifiedSetting] = false; return false; + } - return File.Exists(settingFile); + bool exists = File.Exists(settingFile); + _cache[purifiedSetting] = exists; + return exists; } public static async Task TrySet(string setting, bool enabled) { - string purifiedUser = CoreTools.MakeValidFileName(Environment.UserName); string purifiedSetting = CoreTools.MakeValidFileName(setting); + _cache.Remove(purifiedSetting); + + string purifiedUser = CoreTools.MakeValidFileName(Environment.UserName); using Process p = new Process(); p.StartInfo = new() @@ -56,8 +70,10 @@ public static int ApplyForUser(string username, string setting, bool enable) { try { - string purifiedUser = CoreTools.MakeValidFileName(username); string purifiedSetting = CoreTools.MakeValidFileName(setting); + _cache.Remove(purifiedSetting); + + string purifiedUser = CoreTools.MakeValidFileName(username); var appData = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles); var settingsLocation = Path.Join(appData, "UniGetUI\\SecureSettings", purifiedUser); diff --git a/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Classes/InstallOptionsFactory.cs b/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Classes/InstallOptionsFactory.cs index b0121b0f46..f244fa64af 100644 --- a/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Classes/InstallOptionsFactory.cs +++ b/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Classes/InstallOptionsFactory.cs @@ -1,13 +1,10 @@ using System.Collections.Concurrent; -using System.Runtime.InteropServices; using System.Text.Json; using System.Text.Json.Nodes; -using ABI.Windows.UI.Text.Core; using UniGetUI.Core.Data; -using UniGetUI.Core.Language; using UniGetUI.Core.Logging; +using UniGetUI.Core.SettingsEngine.SecureSettings; using UniGetUI.Core.Tools; -using UniGetUI.PackageEngine.Enums; using UniGetUI.PackageEngine.Interfaces; using UniGetUI.PackageEngine.Serializable; @@ -90,7 +87,7 @@ public static InstallOptions LoadApplicable( if (no_integrity is not null) instance.SkipHashCheck = (bool)no_integrity; if (remove_data is not null) instance.RemoveDataOnUninstall = (bool)remove_data; - return instance; + return EnsureSecureOptions(instance); } /// @@ -112,7 +109,7 @@ public static Task LoadApplicableAsync( bool? no_integrity = null, bool? remove_data = null, InstallOptions? overridePackageOptions = null) - => Task.Run(() => LoadApplicable(package, elevated, interactive, no_integrity, remove_data)); + => Task.Run(() => LoadApplicable(package, elevated, interactive, no_integrity, remove_data, overridePackageOptions)); /* * @@ -186,5 +183,33 @@ private static InstallOptions _loadFromDisk(string key) return new(); } } + + private static InstallOptions EnsureSecureOptions(InstallOptions options) + { + if (SecureSettings.Get("AllowCLIArguments")) + { + // If CLI arguments are allowed, sanitize them + for (int i = 0; i < options.CustomParameters.Count; i++) + { + options.CustomParameters[i] = options.CustomParameters[i] + .Replace("&", "") + .Replace("|", "") + .Replace(";", "") + .Replace("<", "") + .Replace(">", "") + .Replace("\n", ""); + } + } + else + { + // Otherwhise, clear them + if (options.CustomParameters.Count > 0) + Logger.Warn($"Custom CLI parameters [{string.Join(' ', options.CustomParameters)}] will be discarded"); + + options.CustomParameters = []; + } + + return options; + } } } diff --git a/src/UniGetUI.PackageEngine.PackageManagerClasses/UniGetUI.PackageEngine.Classes.csproj b/src/UniGetUI.PackageEngine.PackageManagerClasses/UniGetUI.PackageEngine.Classes.csproj index ceedce4d0e..7a21a8a0f8 100644 --- a/src/UniGetUI.PackageEngine.PackageManagerClasses/UniGetUI.PackageEngine.Classes.csproj +++ b/src/UniGetUI.PackageEngine.PackageManagerClasses/UniGetUI.PackageEngine.Classes.csproj @@ -7,6 +7,7 @@ + diff --git a/src/UniGetUI.PackageEngine.Serializable/InstallOptions.cs b/src/UniGetUI.PackageEngine.Serializable/InstallOptions.cs index 0073e05a5a..82baacad23 100644 --- a/src/UniGetUI.PackageEngine.Serializable/InstallOptions.cs +++ b/src/UniGetUI.PackageEngine.Serializable/InstallOptions.cs @@ -62,22 +62,6 @@ public override void LoadFromJson(JsonNode data) // This entry shall be checked the last one, to ensure all other properties are set this.OverridesNextLevelOpts = data[nameof(OverridesNextLevelOpts)]?.GetValue() ?? DiffersFromDefault(); - - SanitizeOptions(); - } - - private void SanitizeOptions() - { - for (int i = 0; i < this.CustomParameters.Count; i++) - { - this.CustomParameters[i] = this.CustomParameters[i] - .Replace("&", "") - .Replace("|", "") - .Replace(";", "") - .Replace("<", "") - .Replace(">", "") - .Replace("\n", ""); - } } public bool DiffersFromDefault() diff --git a/src/UniGetUI/Controls/SettingsWidgets/CheckboxCard.cs b/src/UniGetUI/Controls/SettingsWidgets/CheckboxCard.cs index 5ee7ddcf05..c86d2a2208 100644 --- a/src/UniGetUI/Controls/SettingsWidgets/CheckboxCard.cs +++ b/src/UniGetUI/Controls/SettingsWidgets/CheckboxCard.cs @@ -1,6 +1,7 @@ using CommunityToolkit.WinUI.Controls; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; +using Microsoft.UI.Xaml.Media; using UniGetUI.Core.SettingsEngine; using UniGetUI.Core.Tools; @@ -13,6 +14,7 @@ public partial class CheckboxCard : SettingsCard { public ToggleSwitch _checkbox; public TextBlock _textblock; + public TextBlock _warningBlock; protected bool IS_INVERTED; protected string setting_name = ""; @@ -40,6 +42,20 @@ public string Text set => _textblock.Text = CoreTools.Translate(value); } + public string WarningText + { + set + { + _warningBlock.Text = CoreTools.Translate(value); + _warningBlock.Visibility = value.Any() ? Visibility.Visible : Visibility.Collapsed; + } + } + + public Brush WarningForeground + { + set => _warningBlock.Foreground = value; + } + public CheckboxCard() { _checkbox = new ToggleSwitch() @@ -52,9 +68,22 @@ public CheckboxCard() Margin = new Thickness(0, 0, 0, 0), TextWrapping = TextWrapping.Wrap }; + _warningBlock = new TextBlock() + { + VerticalAlignment = VerticalAlignment.Center, + Margin = new Thickness(0, 0, 0, 0), + TextWrapping = TextWrapping.Wrap, + FontSize = 12, + Visibility = Visibility.Collapsed, + }; IS_INVERTED = false; Content = _checkbox; - Header = _textblock; + Header = new StackPanel() + { + Spacing = 4, + Orientation = Orientation.Vertical, + Children = { _textblock, _warningBlock } + }; _checkbox.HorizontalAlignment = HorizontalAlignment.Stretch; _checkbox.Toggled += _checkbox_Toggled; diff --git a/src/UniGetUI/Pages/DialogPages/InstallOptions_Package.xaml.cs b/src/UniGetUI/Pages/DialogPages/InstallOptions_Package.xaml.cs index dcb35a8d6d..f99a5fa432 100644 --- a/src/UniGetUI/Pages/DialogPages/InstallOptions_Package.xaml.cs +++ b/src/UniGetUI/Pages/DialogPages/InstallOptions_Package.xaml.cs @@ -315,10 +315,10 @@ private async void GenerateCommand() { if (!_uiLoaded) return; InstallOptions options = await GetUpdatedOptions(updateIgnoredUpdates: false); - if (!options.OverridesNextLevelOpts) - { - options = await InstallOptionsFactory.LoadApplicableAsync(this.Package, overridePackageOptions: options); - } + //if (!options.OverridesNextLevelOpts) + //{ + options = await InstallOptionsFactory.LoadApplicableAsync(this.Package, overridePackageOptions: options); + //} var op = ProfileComboBox.SelectedIndex switch { diff --git a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Administrator.xaml b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Administrator.xaml index 0ef7051ca6..c47371ff61 100644 --- a/src/UniGetUI/Pages/SettingsPages/GeneralPages/Administrator.xaml +++ b/src/UniGetUI/Pages/SettingsPages/GeneralPages/Administrator.xaml @@ -61,7 +61,7 @@ @@ -80,14 +80,16 @@ FontWeight="SemiBold" Text="Restrictions when importing package bundles" /> - + WarningText="Malformed command-line arguments can break packages, or even gain remote execution. Therefore, importing custom command-line arguments is disabled by default" / + --> + > - + > -