add!:安全面板
This commit is contained in:
@@ -76,6 +76,13 @@
|
||||
<ui:FontIcon Icon="{x:Static ui:SegoeFluentIcons.Shield}" />
|
||||
</ui:SettingsCard.HeaderIcon>
|
||||
</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}"
|
||||
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:NavigationViewItem.Icon>
|
||||
</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>
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ namespace Ink_Canvas.Windows.SettingsViews
|
||||
{ "HomePage", typeof(HomePage) },
|
||||
{ "StartupPage", typeof(StartupPage) },
|
||||
{ "PrivacyPage", typeof(PrivacyPage) },
|
||||
{ "SecurityPage", typeof(SecurityPage) },
|
||||
{ "WindowPage", typeof(WindowPage) },
|
||||
{ "AppearancePage", typeof(AppearancePage) },
|
||||
{ "UpdatePage", typeof(UpdatePage) },
|
||||
|
||||
Reference in New Issue
Block a user