Improve sudo password interaction experience

pull/7656/head
2dust 2025-07-27 10:56:58 +08:00
parent e8cdc29bb5
commit 8704942209
10 changed files with 119 additions and 36 deletions

View File

@ -2202,6 +2202,15 @@ namespace ServiceLib.Resx {
}
}
/// <summary>
/// 查找类似 Incorrect password, please try again. 的本地化字符串。
/// </summary>
public static string SudoIncorrectPasswordTip {
get {
return ResourceManager.GetString("SudoIncorrectPasswordTip", resourceCulture);
}
}
/// <summary>
/// 查找类似 Sudo password has been verified successfully, please ignore the incorrect password prompts! 的本地化字符串。
/// </summary>
@ -3202,7 +3211,7 @@ namespace ServiceLib.Resx {
}
/// <summary>
/// 查找类似 The password you entered cannot be verified, so make sure you enter it correctly. If the application does not work properly due to an incorrect input, please restart the application. The password will not be stored and you will need to enter it again after each restart. 的本地化字符串。
/// 查找类似 The password will be validated via the command line. If a validation error causes the application to malfunction, please restart the application. The password will not be stored and must be entered again after each restart. 的本地化字符串。
/// </summary>
public static string TbSettingsLinuxSudoPasswordTip {
get {

View File

@ -1318,7 +1318,7 @@
<value>رمز عبور sudo سیستم</value>
</data>
<data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve">
<value>رمز عبوری که وارد کرده اید تایید نمی شود، بنابراین مطمئن شوید که آن را به درستی وارد کرده اید. اگر برنامه به دلیل ورودی نادرست به درستی کار نمی کند، لطفاً برنامه را مجدداً راه اندازی کنید. رمز عبور ذخیره نمی شود و پس از هر بار راه اندازی مجدد باید آن را دوباره وارد کنید.</value>
<value>The password will be validated via the command line. If a validation error causes the application to malfunction, please restart the application. The password will not be stored and must be entered again after each restart.</value>
</data>
<data name="TransportHeaderTypeTip5" xml:space="preserve">
<value>*حالت xhttp</value>
@ -1398,4 +1398,7 @@
<data name="SudoPwdVerfiedSuccessTip" xml:space="preserve">
<value>Sudo password has been verified successfully, please ignore the incorrect password prompts!</value>
</data>
<data name="SudoIncorrectPasswordTip" xml:space="preserve">
<value>Incorrect password, please try again.</value>
</data>
</root>

View File

@ -1318,7 +1318,7 @@
<value>Rendszer sudo jelszó</value>
</data>
<data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve">
<value>The password you entered cannot be verified, so make sure you enter it correctly. If the application does not work properly due to an incorrect input, please restart the application. The password will not be stored and you will need to enter it again after each restart.</value>
<value>The password will be validated via the command line. If a validation error causes the application to malfunction, please restart the application. The password will not be stored and must be entered again after each restart.</value>
</data>
<data name="TransportHeaderTypeTip5" xml:space="preserve">
<value>*xhttp mód</value>
@ -1398,4 +1398,7 @@
<data name="SudoPwdVerfiedSuccessTip" xml:space="preserve">
<value>Sudo password has been verified successfully, please ignore the incorrect password prompts!</value>
</data>
<data name="SudoIncorrectPasswordTip" xml:space="preserve">
<value>Incorrect password, please try again.</value>
</data>
</root>

View File

@ -1318,7 +1318,7 @@
<value>System sudo password</value>
</data>
<data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve">
<value>The password you entered cannot be verified, so make sure you enter it correctly. If the application does not work properly due to an incorrect input, please restart the application. The password will not be stored and you will need to enter it again after each restart.</value>
<value>The password will be validated via the command line. If a validation error causes the application to malfunction, please restart the application. The password will not be stored and must be entered again after each restart.</value>
</data>
<data name="TransportHeaderTypeTip5" xml:space="preserve">
<value>*xhttp mode</value>
@ -1398,4 +1398,7 @@
<data name="SudoPwdVerfiedSuccessTip" xml:space="preserve">
<value>Sudo password has been verified successfully, please ignore the incorrect password prompts!</value>
</data>
<data name="SudoIncorrectPasswordTip" xml:space="preserve">
<value>Incorrect password, please try again.</value>
</data>
</root>

View File

@ -1318,7 +1318,7 @@
<value>Пароль sudo системы</value>
</data>
<data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve">
<value>Введенный вами пароль не может быть подтвержден, поэтому убедитесь, что вы ввели его правильно. Если приложение не работает должным образом из-за неправильного ввода, то перезапустите его. Пароль не будет сохранен, и вам придется вводить его заново после каждого перезапуска</value>
<value>The password will be validated via the command line. If a validation error causes the application to malfunction, please restart the application. The password will not be stored and must be entered again after each restart.</value>
</data>
<data name="TransportHeaderTypeTip5" xml:space="preserve">
<value>*XHTTP-режим</value>
@ -1398,4 +1398,7 @@
<data name="SudoPwdVerfiedSuccessTip" xml:space="preserve">
<value>Sudo password has been verified successfully, please ignore the incorrect password prompts!</value>
</data>
<data name="SudoIncorrectPasswordTip" xml:space="preserve">
<value>Incorrect password, please try again.</value>
</data>
</root>

View File

@ -1315,7 +1315,7 @@
<value>系统的 sudo 密码</value>
</data>
<data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve">
<value>输入的密码无法校验,所以请确保输入正确。如果因为输入错误导致无法正常运行时,请重启本应用。 密码不会存储,每次重启后都需要再次输入。</value>
<value>密码将调用命令行校验,如果因为校验错误导致无法正常运行时,请重启本应用。 密码不会存储,每次重启后都需要再次输入。</value>
</data>
<data name="TransportHeaderTypeTip5" xml:space="preserve">
<value>*XHTTP 模式</value>
@ -1395,4 +1395,7 @@
<data name="SudoPwdVerfiedSuccessTip" xml:space="preserve">
<value>sudo 密码已经验证成功,请忽略错误密码提示!</value>
</data>
<data name="SudoIncorrectPasswordTip" xml:space="preserve">
<value>密码错误,请重试。</value>
</data>
</root>

View File

@ -1315,7 +1315,7 @@
<value>系統的 sudo 密碼</value>
</data>
<data name="TbSettingsLinuxSudoPasswordTip" xml:space="preserve">
<value>輸入的密碼無法校驗,所以請確保輸入正確。如果因為輸入錯誤導致無法正常運作時,請重新啟動本應用。 密碼不會儲存,每次重啟後都需要再次輸入。</value>
<value>密碼將調用命令行校驗,如果因為校驗錯誤導致無法正常運行時,請重啟本應用。密碼不會存儲,每次重啟後都需要再次輸入。</value>
</data>
<data name="TransportHeaderTypeTip5" xml:space="preserve">
<value>*xhttp 模式</value>
@ -1395,4 +1395,7 @@
<data name="SudoPwdVerfiedSuccessTip" xml:space="preserve">
<value>sudo 密碼已經驗證成功,請忽略錯誤密碼提示!</value>
</data>
<data name="SudoIncorrectPasswordTip" xml:space="preserve">
<value>密碼錯誤,請重試。</value>
</data>
</root>

View File

@ -436,30 +436,34 @@ public class StatusBarViewModel : MyReactiveObject
private async Task DoEnableTun(bool c)
{
if (_config.TunModeItem.EnableTun != EnableTun)
if (_config.TunModeItem.EnableTun == EnableTun)
{
return;
}
_config.TunModeItem.EnableTun = EnableTun;
if (EnableTun && AllowEnableTun() == false)
{
_config.TunModeItem.EnableTun = EnableTun;
// When running as a non-administrator, reboot to administrator mode
if (EnableTun && AllowEnableTun() == false)
if (Utils.IsWindows())
{
if (Utils.IsWindows())
_config.TunModeItem.EnableTun = false;
Locator.Current.GetService<MainWindowViewModel>()?.RebootAsAdmin();
return;
}
else
{
bool? passwordResult = await _updateView?.Invoke(EViewAction.PasswordInput, null);
if (passwordResult == false)
{
_config.TunModeItem.EnableTun = false;
Locator.Current.GetService<MainWindowViewModel>()?.RebootAsAdmin();
return;
}
else
{
if (await _updateView?.Invoke(EViewAction.PasswordInput, null) == false)
{
_config.TunModeItem.EnableTun = false;
return;
}
}
}
await ConfigHandler.SaveConfig(_config);
Locator.Current.GetService<MainWindowViewModel>()?.Reload();
}
await ConfigHandler.SaveConfig(_config);
Locator.Current.GetService<MainWindowViewModel>()?.Reload();
}
private bool AllowEnableTun()

View File

@ -104,13 +104,15 @@ public partial class StatusBarView : ReactiveUserControl<StatusBarViewModel>
{
var dialog = new SudoPasswordInputView();
var obj = await DialogHost.Show(dialog);
if (obj == null)
var password = obj?.ToString();
if (password.IsNullOrEmpty())
{
togEnableTun.IsChecked = false;
return false;
}
AppHandler.Instance.LinuxSudoPwd = obj.ToString() ?? string.Empty;
AppHandler.Instance.LinuxSudoPwd = password;
return true;
}

View File

@ -1,5 +1,6 @@
using Avalonia.Controls;
using Avalonia.Threading;
using CliWrap.Buffered;
using DialogHostAvalonia;
namespace v2rayN.Desktop.Views;
@ -12,22 +13,71 @@ public partial class SudoPasswordInputView : UserControl
this.Loaded += (s, e) => txtPassword.Focus();
btnSave.Click += (_, _) =>
{
if (string.IsNullOrEmpty(txtPassword.Text))
{
txtPassword.Focus();
return;
}
Dispatcher.UIThread.Post(() =>
{
DialogHost.Close(null, txtPassword.Text);
});
};
btnSave.Click += async (_, _) => await SavePasswordAsync();
btnCancel.Click += (_, _) =>
{
DialogHost.Close(null);
};
}
private async Task SavePasswordAsync()
{
if (txtPassword.Text.IsNullOrEmpty())
{
txtPassword.Focus();
return;
}
var password = txtPassword.Text;
btnSave.IsEnabled = false;
try
{
// Verify if the password is correct
if (await CheckSudoPasswordAsync(password))
{
// Password verification successful, return password and close dialog
await Dispatcher.UIThread.InvokeAsync(() =>
{
DialogHost.Close(null, password);
});
}
else
{
// Password verification failed, display error and let user try again
NoticeHandler.Instance.Enqueue(ResUI.SudoIncorrectPasswordTip);
txtPassword.Focus();
}
}
catch (Exception ex)
{
Logging.SaveLog("SudoPassword", ex);
}
finally
{
btnSave.IsEnabled = true;
}
}
private async Task<bool> CheckSudoPasswordAsync(string password)
{
try
{
// Use sudo -S echo command to verify password
var arg = new List<string>() { "-c", "sudo -S echo SUDO_CHECK" };
var result = await CliWrap.Cli
.Wrap(Global.LinuxBash)
.WithArguments(arg)
.WithStandardInputPipe(CliWrap.PipeSource.FromString(password))
.ExecuteBufferedAsync();
return result.ExitCode == 0;
}
catch (Exception ex)
{
Logging.SaveLog("CheckSudoPassword", ex);
return false;
}
}
}