mirror of
https://github.com/KeyKeeperApp/KeyKeeper.git
synced 2026-04-23 07:56:30 +03:00
commit
This commit is contained in:
18
src/KeyKeeper/PasswordEntryDialog.axaml
Normal file
18
src/KeyKeeper/PasswordEntryDialog.axaml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<Window xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
x:Class="KeyKeeper.PasswordEntryDialog"
|
||||||
|
Title="Введите пароль"
|
||||||
|
Width="300"
|
||||||
|
Height="180">
|
||||||
|
|
||||||
|
<StackPanel Margin="20" VerticalAlignment="Center">
|
||||||
|
<TextBlock Text="Введите мастер-пароль:" Margin="0,0,0,15"/>
|
||||||
|
<TextBox x:Name="PasswordBox" Margin="0,0,0,20"/>
|
||||||
|
|
||||||
|
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Spacing="10">
|
||||||
|
<Button Content="Отмена" Width="80" Click="CancelButton_Click"/>
|
||||||
|
<Button Content="Открыть" Width="80" Click="OpenButton_Click"/>
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
</Window>
|
||||||
36
src/KeyKeeper/PasswordEntryDialog.axaml.cs
Normal file
36
src/KeyKeeper/PasswordEntryDialog.axaml.cs
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Markup.Xaml;
|
||||||
|
|
||||||
|
namespace KeyKeeper
|
||||||
|
{
|
||||||
|
public partial class PasswordEntryDialog : Window
|
||||||
|
{
|
||||||
|
public string Password { get; private set; } = "";
|
||||||
|
public bool Opened { get; private set; } = false;
|
||||||
|
|
||||||
|
public PasswordEntryDialog()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
AvaloniaXamlLoader.Load(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OpenButton_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
var passwordBox = this.FindControl<TextBox>("PasswordBox");
|
||||||
|
Password = passwordBox?.Text ?? "";
|
||||||
|
Opened = true;
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CancelButton_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
Opened = false;
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,9 +7,10 @@ using KeyKeeper.PasswordStore.Crypto;
|
|||||||
|
|
||||||
namespace KeyKeeper;
|
namespace KeyKeeper;
|
||||||
|
|
||||||
public partial class RepositoryWindow: Window
|
public partial class RepositoryWindow : Window
|
||||||
{
|
{
|
||||||
public IPassStore? PassStore { private get; init; }
|
public IPassStore? PassStore { get; init; }
|
||||||
|
public string? MasterPassword { get; init; } // <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
|
||||||
public RepositoryWindow()
|
public RepositoryWindow()
|
||||||
{
|
{
|
||||||
@@ -19,7 +20,12 @@ public partial class RepositoryWindow: Window
|
|||||||
protected override void OnOpened(EventArgs e)
|
protected override void OnOpened(EventArgs e)
|
||||||
{
|
{
|
||||||
base.OnOpened(e);
|
base.OnOpened(e);
|
||||||
if (PassStore!.Locked)
|
|
||||||
PassStore.Unlock(new CompositeKey("blablabla", null));
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
if (PassStore != null && PassStore.Locked && !string.IsNullOrEmpty(MasterPassword))
|
||||||
|
{
|
||||||
|
var compositeKey = new CompositeKey(MasterPassword, null);
|
||||||
|
PassStore.Unlock(compositeKey);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,7 @@ using Avalonia.Input;
|
|||||||
using Avalonia.Interactivity;
|
using Avalonia.Interactivity;
|
||||||
using Avalonia.Platform.Storage;
|
using Avalonia.Platform.Storage;
|
||||||
using KeyKeeper.PasswordStore;
|
using KeyKeeper.PasswordStore;
|
||||||
|
using KeyKeeper.PasswordStore.Crypto;
|
||||||
using KeyKeeper.ViewModels;
|
using KeyKeeper.ViewModels;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -21,7 +22,6 @@ namespace KeyKeeper.Views
|
|||||||
|
|
||||||
private async void CreateNewVault_Click(object sender, RoutedEventArgs e)
|
private async void CreateNewVault_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
// 1. Открываем проводник
|
|
||||||
var file = await StorageProvider.SaveFilePickerAsync(new FilePickerSaveOptions
|
var file = await StorageProvider.SaveFilePickerAsync(new FilePickerSaveOptions
|
||||||
{
|
{
|
||||||
Title = "Создать новое хранилище паролей",
|
Title = "Создать новое хранилище паролей",
|
||||||
@@ -29,34 +29,32 @@ namespace KeyKeeper.Views
|
|||||||
DefaultExtension = "kkp",
|
DefaultExtension = "kkp",
|
||||||
FileTypeChoices = new[]
|
FileTypeChoices = new[]
|
||||||
{
|
{
|
||||||
new FilePickerFileType("Хранилище KeyKeeper")
|
new FilePickerFileType("Хранилище KeyKeeper")
|
||||||
{
|
{
|
||||||
Patterns = new[] { "*.kkp" }
|
Patterns = new[] { "*.kkp" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (file != null)
|
if (file != null)
|
||||||
{
|
{
|
||||||
if (file.TryGetLocalPath() is string path)
|
if (file.TryGetLocalPath() is string path)
|
||||||
{
|
{
|
||||||
// 2. Открываем окно с паролем
|
|
||||||
var passwordDialog = new PasswordDialog();
|
var passwordDialog = new PasswordDialog();
|
||||||
await passwordDialog.ShowDialog(this);
|
await passwordDialog.ShowDialog(this);
|
||||||
|
if (passwordDialog.Created && !string.IsNullOrEmpty(passwordDialog.Password))
|
||||||
// 3. Если нажали "Создать"
|
|
||||||
if (passwordDialog.Created)
|
|
||||||
{
|
{
|
||||||
// 4. Создаем хранилище с паролем
|
var compositeKey = new CompositeKey(passwordDialog.Password, null);
|
||||||
var compositeKey = new PasswordStore.Crypto.CompositeKey(passwordDialog.Password, null);
|
var passStoreAccessor = new PassStoreFileAccessor(
|
||||||
(DataContext as MainWindowViewModel)!.CreateVault(path);
|
filename: path,
|
||||||
|
create: true,
|
||||||
// 5. Открываем окно хранилища
|
createOptions: new StoreCreationOptions()
|
||||||
OpenRepositoryWindow(new PassStoreFileAccessor(path, true, new StoreCreationOptions()
|
{
|
||||||
{
|
Key = compositeKey,
|
||||||
Key = compositeKey,
|
LockTimeoutSeconds = 800
|
||||||
LockTimeoutSeconds = 800,
|
});
|
||||||
}));
|
IPassStore passStore = passStoreAccessor;
|
||||||
|
OpenRepositoryWindow(passStore, passwordDialog.Password);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -64,22 +62,21 @@ namespace KeyKeeper.Views
|
|||||||
|
|
||||||
private async void OpenExistingVault_Click(object sender, RoutedEventArgs e)
|
private async void OpenExistingVault_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
// Открываем диалог выбора файла
|
|
||||||
var files = await StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
var files = await StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||||
{
|
{
|
||||||
Title = "Открыть хранилище паролей",
|
Title = "Открыть хранилище паролей",
|
||||||
AllowMultiple = false,
|
AllowMultiple = false,
|
||||||
FileTypeFilter = new[]
|
FileTypeFilter = new[]
|
||||||
{
|
{
|
||||||
new FilePickerFileType("Хранилище KeyKeeper")
|
new FilePickerFileType("Хранилище KeyKeeper")
|
||||||
{
|
{
|
||||||
Patterns = new[] { "*.kkp" }
|
Patterns = new[] { "*.kkp" }
|
||||||
},
|
},
|
||||||
new FilePickerFileType("Все файлы")
|
new FilePickerFileType("Все файлы")
|
||||||
{
|
{
|
||||||
Patterns = new[] { "*.*" }
|
Patterns = new[] { "*.*" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (files.Count > 0)
|
if (files.Count > 0)
|
||||||
@@ -87,20 +84,32 @@ namespace KeyKeeper.Views
|
|||||||
var file = files[0];
|
var file = files[0];
|
||||||
if (file.TryGetLocalPath() is string path)
|
if (file.TryGetLocalPath() is string path)
|
||||||
{
|
{
|
||||||
(DataContext as MainWindowViewModel)!.OpenVault(path);
|
var passwordDialog = new PasswordEntryDialog();
|
||||||
OpenRepositoryWindow(new PassStoreFileAccessor(path, false, null));
|
await passwordDialog.ShowDialog(this);
|
||||||
|
if (passwordDialog.Opened && !string.IsNullOrEmpty(passwordDialog.Password))
|
||||||
|
{
|
||||||
|
var passStoreAccessor = new PassStoreFileAccessor(
|
||||||
|
filename: path,
|
||||||
|
create: false,
|
||||||
|
createOptions: null);
|
||||||
|
IPassStore passStore = passStoreAccessor;
|
||||||
|
(DataContext as MainWindowViewModel)!.OpenVault(path);
|
||||||
|
OpenRepositoryWindow(passStore, passwordDialog.Password);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OpenRepositoryWindow(IPassStore store)
|
private void OpenRepositoryWindow(IPassStore passStore, string masterPassword)
|
||||||
{
|
{
|
||||||
var repositoryWindow = new RepositoryWindow()
|
var repositoryWindow = new RepositoryWindow()
|
||||||
{
|
{
|
||||||
DataContext = this.DataContext,
|
DataContext = this.DataContext,
|
||||||
PassStore = store,
|
PassStore = passStore,
|
||||||
|
MasterPassword = masterPassword,
|
||||||
WindowStartupLocation = WindowStartupLocation.CenterScreen
|
WindowStartupLocation = WindowStartupLocation.CenterScreen
|
||||||
};
|
};
|
||||||
|
|
||||||
repositoryWindow.Closed += (s, e) => this.Show();
|
repositoryWindow.Closed += (s, e) => this.Show();
|
||||||
repositoryWindow.Show();
|
repositoryWindow.Show();
|
||||||
this.Hide();
|
this.Hide();
|
||||||
|
|||||||
Reference in New Issue
Block a user