add!:安全面板
This commit is contained in:
@@ -76,6 +76,13 @@
|
|||||||
<ui:FontIcon Icon="{x:Static ui:SegoeFluentIcons.Shield}" />
|
<ui:FontIcon Icon="{x:Static ui:SegoeFluentIcons.Shield}" />
|
||||||
</ui:SettingsCard.HeaderIcon>
|
</ui:SettingsCard.HeaderIcon>
|
||||||
</ui:SettingsCard>
|
</ui:SettingsCard>
|
||||||
|
|
||||||
|
<ui:SettingsCard Header="安全" Description="安全密码与进程保护"
|
||||||
|
IsClickEnabled="True" Click="QuickNavCard_Click" Tag="SecurityPage">
|
||||||
|
<ui:SettingsCard.HeaderIcon>
|
||||||
|
<ui:FontIcon Icon="{x:Static ui:SegoeFluentIcons.Permissions}" />
|
||||||
|
</ui:SettingsCard.HeaderIcon>
|
||||||
|
</ui:SettingsCard>
|
||||||
|
|
||||||
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}"
|
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}"
|
||||||
Text="主界面" />
|
Text="主界面" />
|
||||||
|
|||||||
@@ -0,0 +1,112 @@
|
|||||||
|
<ui:Page x:Class="Ink_Canvas.Windows.SettingsViews.Pages.SecurityPage"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:local="clr-namespace:Ink_Canvas.Windows.SettingsViews.Pages"
|
||||||
|
xmlns:ui="http://schemas.inkore.net/lib/ui/wpf/modern"
|
||||||
|
xmlns:ikw="http://schemas.inkore.net/lib/ui/wpf"
|
||||||
|
xmlns:sys="clr-namespace:System;assembly=mscorlib"
|
||||||
|
xmlns:controls="clr-namespace:Ink_Canvas.Controls;assembly=InkCanvas.Controls"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
|
||||||
|
Title="安全">
|
||||||
|
|
||||||
|
<ScrollViewer PanningMode="VerticalFirst">
|
||||||
|
<Grid Margin="59,0,59,0">
|
||||||
|
<FrameworkElement.Resources>
|
||||||
|
<sys:Double x:Key="SettingsCardSpacing">4</sys:Double>
|
||||||
|
<Style x:Key="SettingsSectionHeaderTextBlockStyle"
|
||||||
|
BasedOn="{StaticResource BodyStrongTextBlockStyle}"
|
||||||
|
TargetType="TextBlock">
|
||||||
|
<Style.Setters>
|
||||||
|
<Setter Property="Margin" Value="1,30,0,6" />
|
||||||
|
</Style.Setters>
|
||||||
|
</Style>
|
||||||
|
</FrameworkElement.Resources>
|
||||||
|
<Grid>
|
||||||
|
<ikw:SimpleStackPanel MaxWidth="1000"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
Spacing="{StaticResource SettingsCardSpacing}">
|
||||||
|
|
||||||
|
<!-- 安全密码 -->
|
||||||
|
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}"
|
||||||
|
Text="安全密码" />
|
||||||
|
|
||||||
|
<ui:InfoBar IsClosable="False"
|
||||||
|
IsOpen="True"
|
||||||
|
Severity="Informational"
|
||||||
|
Title="说明"
|
||||||
|
Message="安全密码默认关闭。开启后可用于退出软件、进入设置与重置配置等操作时的二次验证。" />
|
||||||
|
|
||||||
|
<controls:LabeledSettingsCard x:Name="CardPasswordEnabled"
|
||||||
|
Header="启用安全密码"
|
||||||
|
Description="开启后需要设置密码"
|
||||||
|
Icon="{x:Static ui:SegoeFluentIcons.Permissions}"
|
||||||
|
SwitchName="ToggleSwitchPasswordEnabled"
|
||||||
|
Toggled="ToggleSwitchPasswordEnabled_Toggled" />
|
||||||
|
|
||||||
|
<ui:SettingsCard x:Name="CardPasswordManage"
|
||||||
|
Header="密码管理"
|
||||||
|
Description="设置或修改安全密码">
|
||||||
|
<ui:SettingsCard.HeaderIcon>
|
||||||
|
<ui:FontIcon Icon="{x:Static ui:SegoeFluentIcons.Lock}" />
|
||||||
|
</ui:SettingsCard.HeaderIcon>
|
||||||
|
<Button x:Name="BtnSetOrChangePassword"
|
||||||
|
Content="设置/修改密码"
|
||||||
|
MinWidth="120"
|
||||||
|
Click="BtnSetOrChangePassword_Click" />
|
||||||
|
</ui:SettingsCard>
|
||||||
|
|
||||||
|
<controls:LabeledSettingsCard x:Name="CardRequirePasswordOnExit"
|
||||||
|
Header="退出软件需要密码"
|
||||||
|
Description="关闭 InkCanvasForClass 时进行密码验证"
|
||||||
|
Icon="{x:Static ui:SegoeFluentIcons.SignOut}"
|
||||||
|
SwitchName="ToggleSwitchRequirePasswordOnExit"
|
||||||
|
Toggled="ToggleSwitchRequirePasswordOnExit_Toggled" />
|
||||||
|
|
||||||
|
<controls:LabeledSettingsCard x:Name="CardRequirePasswordOnEnterSettings"
|
||||||
|
Header="进入设置需要密码"
|
||||||
|
Description="打开设置面板/新设置窗口时进行验证"
|
||||||
|
Icon="{x:Static ui:SegoeFluentIcons.Settings}"
|
||||||
|
SwitchName="ToggleSwitchRequirePasswordOnEnterSettings"
|
||||||
|
Toggled="ToggleSwitchRequirePasswordOnEnterSettings_Toggled" />
|
||||||
|
|
||||||
|
<controls:LabeledSettingsCard x:Name="CardRequirePasswordOnResetConfig"
|
||||||
|
Header="重置配置需要密码"
|
||||||
|
Description="重置 Settings.json 前进行二次验证"
|
||||||
|
Icon="{x:Static ui:SegoeFluentIcons.Refresh}"
|
||||||
|
SwitchName="ToggleSwitchRequirePasswordOnResetConfig"
|
||||||
|
Toggled="ToggleSwitchRequirePasswordOnResetConfig_Toggled" />
|
||||||
|
|
||||||
|
<controls:LabeledSettingsCard x:Name="CardRequirePasswordOnModifyOrClearNameList"
|
||||||
|
Header="修改/清空点名名单需要密码"
|
||||||
|
Description="对点名名单进行修改或清空前进行验证"
|
||||||
|
Icon="{x:Static ui:SegoeFluentIcons.People}"
|
||||||
|
SwitchName="ToggleSwitchRequirePasswordOnModifyOrClearNameList"
|
||||||
|
Toggled="ToggleSwitchRequirePasswordOnModifyOrClearNameList_Toggled" />
|
||||||
|
|
||||||
|
<!-- 进程保护 -->
|
||||||
|
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}"
|
||||||
|
Text="进程保护" />
|
||||||
|
|
||||||
|
<ui:InfoBar IsClosable="False"
|
||||||
|
IsOpen="True"
|
||||||
|
Severity="Informational"
|
||||||
|
Title="说明"
|
||||||
|
Message="进程保护默认开启:运行期间保护根目录下的程序文件(exe/dll/config)不被外部修改。" />
|
||||||
|
|
||||||
|
<controls:LabeledSettingsCard x:Name="CardEnableProcessProtection"
|
||||||
|
Header="进程保护"
|
||||||
|
Description="开启后关键文件会被只读占用"
|
||||||
|
Icon="{x:Static ui:SegoeFluentIcons.Shield}"
|
||||||
|
SwitchName="ToggleSwitchEnableProcessProtection"
|
||||||
|
Toggled="ToggleSwitchEnableProcessProtection_Toggled" />
|
||||||
|
|
||||||
|
<Rectangle Height="48" />
|
||||||
|
|
||||||
|
</ikw:SimpleStackPanel>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</ScrollViewer>
|
||||||
|
</ui:Page>
|
||||||
@@ -0,0 +1,183 @@
|
|||||||
|
using Ink_Canvas.Helpers;
|
||||||
|
using Ink_Canvas.Windows.SettingsViews.Helpers;
|
||||||
|
using System;
|
||||||
|
using System.Windows;
|
||||||
|
using Page = iNKORE.UI.WPF.Modern.Controls.Page;
|
||||||
|
|
||||||
|
namespace Ink_Canvas.Windows.SettingsViews.Pages
|
||||||
|
{
|
||||||
|
public partial class SecurityPage : Page
|
||||||
|
{
|
||||||
|
private bool _isLoaded = false;
|
||||||
|
|
||||||
|
public SecurityPage()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
Loaded += Page_Loaded;
|
||||||
|
Unloaded += Page_Unloaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Page_Loaded(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
LoadSettings();
|
||||||
|
_isLoaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Page_Unloaded(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
_isLoaded = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadSettings()
|
||||||
|
{
|
||||||
|
_isLoaded = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var settings = SettingsManager.Settings;
|
||||||
|
if (settings == null) return;
|
||||||
|
if (settings.Security == null) settings.Security = new Security();
|
||||||
|
|
||||||
|
var sec = settings.Security;
|
||||||
|
CardPasswordEnabled.IsOn = sec.PasswordEnabled;
|
||||||
|
CardRequirePasswordOnExit.IsOn = sec.RequirePasswordOnExit;
|
||||||
|
CardRequirePasswordOnEnterSettings.IsOn = sec.RequirePasswordOnEnterSettings;
|
||||||
|
CardRequirePasswordOnResetConfig.IsOn = sec.RequirePasswordOnResetConfig;
|
||||||
|
CardRequirePasswordOnModifyOrClearNameList.IsOn = sec.RequirePasswordOnModifyOrClearNameList;
|
||||||
|
CardEnableProcessProtection.IsOn = sec.EnableProcessProtection;
|
||||||
|
|
||||||
|
UpdatePasswordUiState();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
System.Diagnostics.Debug.WriteLine($"加载安全页面设置时出错: {ex.Message}");
|
||||||
|
}
|
||||||
|
_isLoaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdatePasswordUiState()
|
||||||
|
{
|
||||||
|
var sec = SettingsManager.Settings?.Security;
|
||||||
|
var enabled = sec != null && sec.PasswordEnabled;
|
||||||
|
|
||||||
|
if (BtnSetOrChangePassword != null) BtnSetOrChangePassword.IsEnabled = enabled;
|
||||||
|
|
||||||
|
CardRequirePasswordOnExit.IsEnabled = enabled;
|
||||||
|
CardRequirePasswordOnEnterSettings.IsEnabled = enabled;
|
||||||
|
CardRequirePasswordOnResetConfig.IsEnabled = enabled;
|
||||||
|
CardRequirePasswordOnModifyOrClearNameList.IsEnabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetCardIsOnSilently(Ink_Canvas.Controls.LabeledSettingsCard card, bool value)
|
||||||
|
{
|
||||||
|
var prev = _isLoaded;
|
||||||
|
_isLoaded = false;
|
||||||
|
try { card.IsOn = value; }
|
||||||
|
finally { _isLoaded = prev; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void ToggleSwitchPasswordEnabled_Toggled(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (!_isLoaded) return;
|
||||||
|
var settings = SettingsManager.Settings;
|
||||||
|
if (settings == null) return;
|
||||||
|
if (settings.Security == null) settings.Security = new Security();
|
||||||
|
var sec = settings.Security;
|
||||||
|
|
||||||
|
bool newState = CardPasswordEnabled.IsOn;
|
||||||
|
var owner = Window.GetWindow(this);
|
||||||
|
|
||||||
|
if (newState)
|
||||||
|
{
|
||||||
|
var havePassword = SecurityManager.HasPasswordConfigured(settings);
|
||||||
|
if (!havePassword)
|
||||||
|
{
|
||||||
|
var pwd = await SecurityManager.PromptSetNewPasswordAsync(owner);
|
||||||
|
if (string.IsNullOrEmpty(pwd))
|
||||||
|
{
|
||||||
|
SetCardIsOnSilently(CardPasswordEnabled, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SecurityManager.SetPassword(settings, pwd);
|
||||||
|
}
|
||||||
|
|
||||||
|
sec.PasswordEnabled = true;
|
||||||
|
SettingsManager.SaveSettingsToFile();
|
||||||
|
UpdatePasswordUiState();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (SecurityManager.HasPasswordConfigured(settings))
|
||||||
|
{
|
||||||
|
bool ok = await SecurityManager.PromptAndVerifyAsync(settings, owner,
|
||||||
|
"关闭安全密码", "请输入当前密码以关闭安全密码功能。");
|
||||||
|
if (!ok)
|
||||||
|
{
|
||||||
|
SetCardIsOnSilently(CardPasswordEnabled, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sec.PasswordEnabled = false;
|
||||||
|
SecurityManager.ClearPassword(settings);
|
||||||
|
SettingsManager.SaveSettingsToFile();
|
||||||
|
UpdatePasswordUiState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void BtnSetOrChangePassword_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
var settings = SettingsManager.Settings;
|
||||||
|
if (settings == null) return;
|
||||||
|
if (settings.Security == null) settings.Security = new Security();
|
||||||
|
|
||||||
|
var owner = Window.GetWindow(this);
|
||||||
|
var newPwd = await SecurityManager.PromptChangePasswordAsync(settings, owner);
|
||||||
|
if (!string.IsNullOrEmpty(newPwd))
|
||||||
|
{
|
||||||
|
SecurityManager.SetPassword(settings, newPwd);
|
||||||
|
settings.Security.PasswordEnabled = true;
|
||||||
|
SettingsManager.SaveSettingsToFile();
|
||||||
|
|
||||||
|
SetCardIsOnSilently(CardPasswordEnabled, true);
|
||||||
|
UpdatePasswordUiState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ToggleSwitchRequirePasswordOnExit_Toggled(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (!_isLoaded) return;
|
||||||
|
SettingsManager.Settings.Security.RequirePasswordOnExit = CardRequirePasswordOnExit.IsOn;
|
||||||
|
SettingsManager.SaveSettingsToFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ToggleSwitchRequirePasswordOnEnterSettings_Toggled(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (!_isLoaded) return;
|
||||||
|
SettingsManager.Settings.Security.RequirePasswordOnEnterSettings = CardRequirePasswordOnEnterSettings.IsOn;
|
||||||
|
SettingsManager.SaveSettingsToFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ToggleSwitchRequirePasswordOnResetConfig_Toggled(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (!_isLoaded) return;
|
||||||
|
SettingsManager.Settings.Security.RequirePasswordOnResetConfig = CardRequirePasswordOnResetConfig.IsOn;
|
||||||
|
SettingsManager.SaveSettingsToFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ToggleSwitchRequirePasswordOnModifyOrClearNameList_Toggled(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (!_isLoaded) return;
|
||||||
|
SettingsManager.Settings.Security.RequirePasswordOnModifyOrClearNameList = CardRequirePasswordOnModifyOrClearNameList.IsOn;
|
||||||
|
SettingsManager.SaveSettingsToFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ToggleSwitchEnableProcessProtection_Toggled(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (!_isLoaded) return;
|
||||||
|
bool newState = CardEnableProcessProtection.IsOn;
|
||||||
|
SettingsManager.Settings.Security.EnableProcessProtection = newState;
|
||||||
|
SettingsManager.SaveSettingsToFile();
|
||||||
|
ProcessProtectionManager.SetEnabled(newState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -153,6 +153,15 @@
|
|||||||
<ui:FontIcon Icon="{x:Static ui:SegoeFluentIcons.Shield}"/>
|
<ui:FontIcon Icon="{x:Static ui:SegoeFluentIcons.Shield}"/>
|
||||||
</ui:NavigationViewItem.Icon>
|
</ui:NavigationViewItem.Icon>
|
||||||
</ui:NavigationViewItem>
|
</ui:NavigationViewItem>
|
||||||
|
<ui:NavigationViewItem
|
||||||
|
x:Name="SecurityPageItem"
|
||||||
|
Content="安全"
|
||||||
|
Tag="SecurityPage"
|
||||||
|
ToolTipService.ToolTip="安全密码与进程保护">
|
||||||
|
<ui:NavigationViewItem.Icon>
|
||||||
|
<ui:FontIcon Icon="{x:Static ui:SegoeFluentIcons.Permissions}"/>
|
||||||
|
</ui:NavigationViewItem.Icon>
|
||||||
|
</ui:NavigationViewItem>
|
||||||
</ui:NavigationViewItem.MenuItems>
|
</ui:NavigationViewItem.MenuItems>
|
||||||
</ui:NavigationViewItem>
|
</ui:NavigationViewItem>
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ namespace Ink_Canvas.Windows.SettingsViews
|
|||||||
{ "HomePage", typeof(HomePage) },
|
{ "HomePage", typeof(HomePage) },
|
||||||
{ "StartupPage", typeof(StartupPage) },
|
{ "StartupPage", typeof(StartupPage) },
|
||||||
{ "PrivacyPage", typeof(PrivacyPage) },
|
{ "PrivacyPage", typeof(PrivacyPage) },
|
||||||
|
{ "SecurityPage", typeof(SecurityPage) },
|
||||||
{ "WindowPage", typeof(WindowPage) },
|
{ "WindowPage", typeof(WindowPage) },
|
||||||
{ "AppearancePage", typeof(AppearancePage) },
|
{ "AppearancePage", typeof(AppearancePage) },
|
||||||
{ "UpdatePage", typeof(UpdatePage) },
|
{ "UpdatePage", typeof(UpdatePage) },
|
||||||
|
|||||||
Reference in New Issue
Block a user