mirror of
https://github.com/wismna/ModernKeePass.git
synced 2025-10-03 23:50:18 -04:00
Compare commits
26 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
4aefbcb8b9 | ||
![]() |
56129253d9 | ||
![]() |
7613629d87 | ||
![]() |
fb0eab00c2 | ||
![]() |
5b8c3b9b11 | ||
![]() |
700f76679a | ||
![]() |
e7d731bb04 | ||
![]() |
49637fcc3b | ||
![]() |
fc25d7ea93 | ||
![]() |
cca6579274 | ||
![]() |
7dbf93fe7b | ||
![]() |
b46ab8db51 | ||
![]() |
a19519fa73 | ||
![]() |
4a3f36d38b | ||
![]() |
4ae02fc07b | ||
![]() |
047fca32bf | ||
![]() |
abbff449c0 | ||
![]() |
fba668860b | ||
![]() |
acb196d9c2 | ||
![]() |
dfa3a21e6b | ||
![]() |
7ff6bccbc4 | ||
![]() |
88e5b80778 | ||
![]() |
d127431396 | ||
![]() |
588703ecd6 | ||
![]() |
223c9b641a | ||
![]() |
7db34d6517 |
33
ModernKeePass/Actions/NavigateToUrlAction.cs
Normal file
33
ModernKeePass/Actions/NavigateToUrlAction.cs
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
using System;
|
||||||
|
using Windows.UI.Xaml;
|
||||||
|
using Microsoft.Xaml.Interactivity;
|
||||||
|
using ModernKeePass.Common;
|
||||||
|
|
||||||
|
namespace ModernKeePass.Actions
|
||||||
|
{
|
||||||
|
public class NavigateToUrlAction : DependencyObject, IAction
|
||||||
|
{
|
||||||
|
public string Url
|
||||||
|
{
|
||||||
|
get { return (string)GetValue(UrlProperty); }
|
||||||
|
set { SetValue(UrlProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty UrlProperty =
|
||||||
|
DependencyProperty.Register("Url", typeof(string), typeof(NavigateToUrlAction), new PropertyMetadata(string.Empty));
|
||||||
|
|
||||||
|
public object Execute(object sender, object parameter)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var uri = new Uri(Url);
|
||||||
|
return Windows.System.Launcher.LaunchUriAsync(uri).GetAwaiter().GetResult();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageDialogHelper.ShowErrorDialog(ex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
14
ModernKeePass/Aop/DatabaseChanged.cs
Normal file
14
ModernKeePass/Aop/DatabaseChanged.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using ModernKeePass.Services;
|
||||||
|
|
||||||
|
namespace ModernKeePass.Attributes
|
||||||
|
{
|
||||||
|
[AttributeUsage(AttributeTargets.All)]
|
||||||
|
public class DatabaseChangedAttribute: Attribute
|
||||||
|
{
|
||||||
|
public DatabaseChangedAttribute()
|
||||||
|
{
|
||||||
|
DatabaseService.Instance.HasChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
26
ModernKeePass/Aop/DatabaseChangedProxy.cs
Normal file
26
ModernKeePass/Aop/DatabaseChangedProxy.cs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using ModernKeePass.Interfaces;
|
||||||
|
|
||||||
|
namespace ModernKeePass.Aop
|
||||||
|
{
|
||||||
|
public class DatabaseChangedProxy<T>: IProxyInvocationHandler
|
||||||
|
{
|
||||||
|
private readonly T _decorated;
|
||||||
|
private readonly IDatabaseService _databaseService;
|
||||||
|
|
||||||
|
public DatabaseChangedProxy(T decorated, IDatabaseService databaseService)
|
||||||
|
{
|
||||||
|
_decorated = decorated;
|
||||||
|
_databaseService = databaseService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public object Invoke(object proxy, MethodInfo method, object[] parameters)
|
||||||
|
{
|
||||||
|
object retVal = null;
|
||||||
|
retVal = method.Invoke(proxy, parameters);
|
||||||
|
_databaseService.HasChanged = true;
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -6,6 +6,9 @@ using Windows.Storage;
|
|||||||
using Windows.UI.Xaml;
|
using Windows.UI.Xaml;
|
||||||
using Windows.UI.Xaml.Controls;
|
using Windows.UI.Xaml.Controls;
|
||||||
using Windows.UI.Xaml.Navigation;
|
using Windows.UI.Xaml.Navigation;
|
||||||
|
using Microsoft.AppCenter;
|
||||||
|
using Microsoft.AppCenter.Analytics;
|
||||||
|
using Microsoft.AppCenter.Push;
|
||||||
using ModernKeePass.Common;
|
using ModernKeePass.Common;
|
||||||
using ModernKeePass.Exceptions;
|
using ModernKeePass.Exceptions;
|
||||||
using ModernKeePass.Services;
|
using ModernKeePass.Services;
|
||||||
@@ -20,19 +23,20 @@ namespace ModernKeePass
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
sealed partial class App
|
sealed partial class App
|
||||||
{
|
{
|
||||||
public DatabaseService Database { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes the singleton application object. This is the first line of authored code
|
/// Initializes the singleton application object. This is the first line of authored code
|
||||||
/// executed, and as such is the logical equivalent of main() or WinMain().
|
/// executed, and as such is the logical equivalent of main() or WinMain().
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public App()
|
public App()
|
||||||
{
|
{
|
||||||
|
AppCenter.Start("79d23520-a486-4f63-af81-8d90bf4e1bea", typeof(Analytics), typeof(Push));
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
Suspending += OnSuspending;
|
Suspending += OnSuspending;
|
||||||
|
Resuming += OnResuming;
|
||||||
UnhandledException += OnUnhandledException;
|
UnhandledException += OnUnhandledException;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#region Event Handlers
|
#region Event Handlers
|
||||||
|
|
||||||
private void OnUnhandledException(object sender, UnhandledExceptionEventArgs unhandledExceptionEventArgs)
|
private void OnUnhandledException(object sender, UnhandledExceptionEventArgs unhandledExceptionEventArgs)
|
||||||
@@ -45,9 +49,16 @@ namespace ModernKeePass
|
|||||||
? exception.InnerException
|
? exception.InnerException
|
||||||
: exception;
|
: exception;
|
||||||
|
|
||||||
if (!(realException is SaveException)) return;
|
if (realException is SaveException)
|
||||||
|
{
|
||||||
unhandledExceptionEventArgs.Handled = true;
|
unhandledExceptionEventArgs.Handled = true;
|
||||||
MessageDialogHelper.SaveErrorDialog(realException as SaveException, Database);
|
MessageDialogHelper.SaveErrorDialog(realException as SaveException, DatabaseService.Instance);
|
||||||
|
}
|
||||||
|
else if (realException is DatabaseOpenedException)
|
||||||
|
{
|
||||||
|
unhandledExceptionEventArgs.Handled = true;
|
||||||
|
MessageDialogHelper.SaveUnchangedDialog(realException as DatabaseOpenedException, DatabaseService.Instance);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -89,7 +100,10 @@ namespace ModernKeePass
|
|||||||
|
|
||||||
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
|
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
|
||||||
{
|
{
|
||||||
//TODO: Load state from previously suspended application
|
//TODO: Load state from previously terminated application
|
||||||
|
#if DEBUG
|
||||||
|
MessageDialogHelper.ShowNotificationDialog("App terminated", "Windows or an error made the app terminate");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Place the frame in the current Window
|
// Place the frame in the current Window
|
||||||
@@ -122,7 +136,31 @@ namespace ModernKeePass
|
|||||||
}*/
|
}*/
|
||||||
// Ensure the current window is active
|
// Ensure the current window is active
|
||||||
Window.Current.Activate();
|
Window.Current.Activate();
|
||||||
Database = new DatabaseService();
|
}
|
||||||
|
|
||||||
|
private async void OnResuming(object sender, object e)
|
||||||
|
{
|
||||||
|
var currentFrame = Window.Current.Content as Frame;
|
||||||
|
var database = DatabaseService.Instance;
|
||||||
|
if (database.DatabaseFile == null)
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
ToastNotificationHelper.ShowGenericToast("App suspended", "Nothing to do, no previous database opened");
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (database.CompositeKey != null) await database.ReOpen();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
currentFrame?.Navigate(typeof(MainPage));
|
||||||
|
#if DEBUG
|
||||||
|
MessageDialogHelper.ShowErrorDialog(ex);
|
||||||
|
#endif
|
||||||
|
ToastNotificationHelper.ShowGenericToast("App suspended", "Database was closed (changes were saved)");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -142,11 +180,21 @@ namespace ModernKeePass
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sender">The source of the suspend request.</param>
|
/// <param name="sender">The source of the suspend request.</param>
|
||||||
/// <param name="e">Details about the suspend request.</param>
|
/// <param name="e">Details about the suspend request.</param>
|
||||||
private void OnSuspending(object sender, SuspendingEventArgs e)
|
private async void OnSuspending(object sender, SuspendingEventArgs e)
|
||||||
{
|
{
|
||||||
var deferral = e.SuspendingOperation.GetDeferral();
|
var deferral = e.SuspendingOperation.GetDeferral();
|
||||||
UnhandledException -= OnUnhandledException;
|
var database = DatabaseService.Instance;
|
||||||
Database.Save();
|
try
|
||||||
|
{
|
||||||
|
if (SettingsService.Instance.GetSetting("SaveSuspend", true)) database.Save();
|
||||||
|
await database.Close(false);
|
||||||
|
}
|
||||||
|
catch (Exception exception)
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
ToastNotificationHelper.ShowErrorToast(exception);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
deferral.Complete();
|
deferral.Complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,7 +206,7 @@ namespace ModernKeePass
|
|||||||
{
|
{
|
||||||
base.OnFileActivated(args);
|
base.OnFileActivated(args);
|
||||||
var rootFrame = new Frame();
|
var rootFrame = new Frame();
|
||||||
Database.DatabaseFile = args.Files[0] as StorageFile;
|
DatabaseService.Instance.DatabaseFile = args.Files[0] as StorageFile;
|
||||||
rootFrame.Navigate(typeof(MainPage), args);
|
rootFrame.Navigate(typeof(MainPage), args);
|
||||||
Window.Current.Content = rootFrame;
|
Window.Current.Content = rootFrame;
|
||||||
Window.Current.Activate();
|
Window.Current.Activate();
|
||||||
|
@@ -2,7 +2,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Windows.Storage.Pickers;
|
using Windows.Storage.Pickers;
|
||||||
using Windows.UI.Popups;
|
using Windows.UI.Popups;
|
||||||
using Windows.UI.Xaml.Media.Animation;
|
|
||||||
using ModernKeePass.Exceptions;
|
using ModernKeePass.Exceptions;
|
||||||
using ModernKeePass.Interfaces;
|
using ModernKeePass.Interfaces;
|
||||||
|
|
||||||
@@ -10,19 +9,20 @@ namespace ModernKeePass.Common
|
|||||||
{
|
{
|
||||||
public static class MessageDialogHelper
|
public static class MessageDialogHelper
|
||||||
{
|
{
|
||||||
public static async void ShowActionDialog(string title, string contentText, string actionButtonText, string cancelButtonText, UICommandInvokedHandler action)
|
// TODO: include resources
|
||||||
|
public static async void ShowActionDialog(string title, string contentText, string actionButtonText, string cancelButtonText, UICommandInvokedHandler actionCommand, UICommandInvokedHandler cancelCommand)
|
||||||
{
|
{
|
||||||
// Create the message dialog and set its content
|
// Create the message dialog and set its content
|
||||||
var messageDialog = CreateBasicDialog(title, contentText, cancelButtonText);
|
var messageDialog = CreateBasicDialog(title, contentText, cancelButtonText, cancelCommand);
|
||||||
|
|
||||||
// Add commands and set their callbacks; both buttons use the same callback function instead of inline event handlers
|
// Add commands and set their callbacks; both buttons use the same callback function instead of inline event handlers
|
||||||
messageDialog.Commands.Add(new UICommand(actionButtonText, action));
|
messageDialog.Commands.Add(new UICommand(actionButtonText, actionCommand));
|
||||||
|
|
||||||
// Show the message dialog
|
// Show the message dialog
|
||||||
await messageDialog.ShowAsync();
|
await messageDialog.ShowAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SaveErrorDialog(SaveException exception, IDatabase database)
|
public static void SaveErrorDialog(SaveException exception, IDatabaseService database)
|
||||||
{
|
{
|
||||||
ShowActionDialog("Save error", exception.InnerException.Message, "Save as", "Discard", async command =>
|
ShowActionDialog("Save error", exception.InnerException.Message, "Save as", "Discard", async command =>
|
||||||
{
|
{
|
||||||
@@ -35,6 +35,19 @@ namespace ModernKeePass.Common
|
|||||||
|
|
||||||
var file = await savePicker.PickSaveFileAsync();
|
var file = await savePicker.PickSaveFileAsync();
|
||||||
if (file != null) database.Save(file);
|
if (file != null) database.Save(file);
|
||||||
|
}, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SaveUnchangedDialog(DatabaseOpenedException exception, IDatabaseService database)
|
||||||
|
{
|
||||||
|
ShowActionDialog("Opened database", $"Database {database.Name} is currently opened. What to you wish to do?", "Save changes", "Discard", command =>
|
||||||
|
{
|
||||||
|
database.Save();
|
||||||
|
database.Close();
|
||||||
|
},
|
||||||
|
command =>
|
||||||
|
{
|
||||||
|
database.Close();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,7 +55,7 @@ namespace ModernKeePass.Common
|
|||||||
{
|
{
|
||||||
if (exception == null) return;
|
if (exception == null) return;
|
||||||
// Create the message dialog and set its content
|
// Create the message dialog and set its content
|
||||||
var messageDialog = CreateBasicDialog("Error occured", exception.Message, "OK");
|
var messageDialog = CreateBasicDialog(exception.Message, exception.StackTrace, "OK");
|
||||||
|
|
||||||
// Show the message dialog
|
// Show the message dialog
|
||||||
await messageDialog.ShowAsync();
|
await messageDialog.ShowAsync();
|
||||||
@@ -56,13 +69,13 @@ namespace ModernKeePass.Common
|
|||||||
await dialog.ShowAsync();
|
await dialog.ShowAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MessageDialog CreateBasicDialog(string title, string message, string dismissActionText)
|
private static MessageDialog CreateBasicDialog(string title, string message, string dismissActionText, UICommandInvokedHandler cancelCommand = null)
|
||||||
{
|
{
|
||||||
// Create the message dialog and set its content
|
// Create the message dialog and set its content
|
||||||
var messageDialog = new MessageDialog(message, title);
|
var messageDialog = new MessageDialog(message, title);
|
||||||
|
|
||||||
// Add commands and set their callbacks;
|
// Add commands and set their callbacks;
|
||||||
messageDialog.Commands.Add(new UICommand(dismissActionText));
|
messageDialog.Commands.Add(new UICommand(dismissActionText, cancelCommand));
|
||||||
|
|
||||||
// Set the command that will be invoked by default
|
// Set the command that will be invoked by default
|
||||||
messageDialog.DefaultCommandIndex = 1;
|
messageDialog.DefaultCommandIndex = 1;
|
||||||
|
@@ -45,5 +45,10 @@ namespace ModernKeePass.Common
|
|||||||
};
|
};
|
||||||
ToastNotificationManager.CreateToastNotifier().Show(toast);
|
ToastNotificationManager.CreateToastNotifier().Show(toast);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void ShowErrorToast(Exception exception)
|
||||||
|
{
|
||||||
|
ShowGenericToast(exception.Source, exception.Message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,20 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Windows.UI.Text;
|
|
||||||
using Windows.UI.Xaml.Data;
|
|
||||||
|
|
||||||
namespace ModernKeePass.Converters
|
|
||||||
{
|
|
||||||
public class BooleanToFontStyleConverter : IValueConverter
|
|
||||||
{
|
|
||||||
public object Convert(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
var boolean = value is bool ? (bool)value : false;
|
|
||||||
return boolean ? FontStyle.Italic : FontStyle.Normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
9
ModernKeePass/Exceptions/DatabaseOpenedException.cs
Normal file
9
ModernKeePass/Exceptions/DatabaseOpenedException.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace ModernKeePass.Exceptions
|
||||||
|
{
|
||||||
|
public class DatabaseOpenedException: Exception
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -1,4 +1,5 @@
|
|||||||
using Windows.Storage;
|
using System.Threading.Tasks;
|
||||||
|
using Windows.Storage;
|
||||||
using ModernKeePass.ViewModels;
|
using ModernKeePass.ViewModels;
|
||||||
using ModernKeePassLib;
|
using ModernKeePassLib;
|
||||||
using ModernKeePassLib.Cryptography.KeyDerivation;
|
using ModernKeePassLib.Cryptography.KeyDerivation;
|
||||||
@@ -6,24 +7,29 @@ using ModernKeePassLib.Keys;
|
|||||||
|
|
||||||
namespace ModernKeePass.Interfaces
|
namespace ModernKeePass.Interfaces
|
||||||
{
|
{
|
||||||
public interface IDatabase
|
public interface IDatabaseService
|
||||||
{
|
{
|
||||||
string Name { get; }
|
string Name { get; }
|
||||||
bool RecycleBinEnabled { get; set; }
|
bool RecycleBinEnabled { get; set; }
|
||||||
int Status { get; set; }
|
//int Status { get; set; }
|
||||||
GroupVm RootGroup { get; set; }
|
GroupVm RootGroup { get; set; }
|
||||||
GroupVm RecycleBin { get; set; }
|
GroupVm RecycleBin { get; set; }
|
||||||
StorageFile DatabaseFile { get; set; }
|
StorageFile DatabaseFile { get; set; }
|
||||||
|
CompositeKey CompositeKey { get; set; }
|
||||||
PwUuid DataCipher { get; set; }
|
PwUuid DataCipher { get; set; }
|
||||||
PwCompressionAlgorithm CompressionAlgorithm { get; set; }
|
PwCompressionAlgorithm CompressionAlgorithm { get; set; }
|
||||||
KdfParameters KeyDerivation { get; set; }
|
KdfParameters KeyDerivation { get; set; }
|
||||||
|
bool IsOpen { get; }
|
||||||
|
bool IsFileOpen { get; }
|
||||||
|
bool IsClosed { get; }
|
||||||
|
bool HasChanged { get; set; }
|
||||||
|
|
||||||
void Open(CompositeKey key, bool createNew);
|
Task Open(CompositeKey key, bool createNew = false);
|
||||||
void UpdateCompositeKey(CompositeKey key);
|
Task ReOpen();
|
||||||
void Save();
|
void Save();
|
||||||
void Save(StorageFile file);
|
void Save(StorageFile file);
|
||||||
void CreateRecycleBin();
|
void CreateRecycleBin(string title);
|
||||||
void AddDeletedItem(PwUuid id);
|
void AddDeletedItem(PwUuid id);
|
||||||
void Close();
|
Task Close(bool releaseFile = true);
|
||||||
}
|
}
|
||||||
}
|
}
|
9
ModernKeePass/Interfaces/IProxyInvocationHandler.cs
Normal file
9
ModernKeePass/Interfaces/IProxyInvocationHandler.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace ModernKeePass.Interfaces
|
||||||
|
{
|
||||||
|
public interface IProxyInvocationHandler
|
||||||
|
{
|
||||||
|
object Invoke(object proxy, MethodInfo method, object[] parameters);
|
||||||
|
}
|
||||||
|
}
|
@@ -34,6 +34,6 @@ namespace ModernKeePass.Interfaces
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Delete from ViewModel
|
/// Delete from ViewModel
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void MarkForDelete();
|
void MarkForDelete(string recycleBinTitle);
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -4,7 +4,7 @@ using Windows.Storage;
|
|||||||
|
|
||||||
namespace ModernKeePass.Interfaces
|
namespace ModernKeePass.Interfaces
|
||||||
{
|
{
|
||||||
public interface IRecent
|
public interface IRecentService
|
||||||
{
|
{
|
||||||
int EntryCount { get; }
|
int EntryCount { get; }
|
||||||
Task<IStorageItem> GetFileAsync(string token);
|
Task<IStorageItem> GetFileAsync(string token);
|
@@ -1,6 +1,6 @@
|
|||||||
namespace ModernKeePass.Interfaces
|
namespace ModernKeePass.Interfaces
|
||||||
{
|
{
|
||||||
public interface IResource
|
public interface IResourceService
|
||||||
{
|
{
|
||||||
string GetResourceValue(string key);
|
string GetResourceValue(string key);
|
||||||
}
|
}
|
@@ -1,8 +0,0 @@
|
|||||||
namespace ModernKeePass.Interfaces
|
|
||||||
{
|
|
||||||
public interface ISettings
|
|
||||||
{
|
|
||||||
T GetSetting<T>(string property);
|
|
||||||
void PutSetting<T>(string property, T value);
|
|
||||||
}
|
|
||||||
}
|
|
8
ModernKeePass/Interfaces/ISettingsService.cs
Normal file
8
ModernKeePass/Interfaces/ISettingsService.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
namespace ModernKeePass.Interfaces
|
||||||
|
{
|
||||||
|
public interface ISettingsService
|
||||||
|
{
|
||||||
|
T GetSetting<T>(string property, T defaultValue = default(T));
|
||||||
|
void PutSetting<T>(string property, T value);
|
||||||
|
}
|
||||||
|
}
|
@@ -109,20 +109,27 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Actions\ClipboardAction.cs" />
|
<Compile Include="Actions\ClipboardAction.cs" />
|
||||||
|
<Compile Include="Actions\NavigateToUrlAction.cs" />
|
||||||
<Compile Include="Actions\SetupFocusAction.cs" />
|
<Compile Include="Actions\SetupFocusAction.cs" />
|
||||||
|
<Compile Include="Aop\DatabaseChangedProxy.cs" />
|
||||||
<Compile Include="App.xaml.cs">
|
<Compile Include="App.xaml.cs">
|
||||||
<DependentUpon>App.xaml</DependentUpon>
|
<DependentUpon>App.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Aop\DatabaseChanged.cs" />
|
||||||
|
<Compile Include="Exceptions\DatabaseOpenedException.cs" />
|
||||||
<Compile Include="Interfaces\ILicenseService.cs" />
|
<Compile Include="Interfaces\ILicenseService.cs" />
|
||||||
<Compile Include="Interfaces\IRecent.cs" />
|
<Compile Include="Interfaces\IProxyInvocationHandler.cs" />
|
||||||
|
<Compile Include="Interfaces\IRecentService.cs" />
|
||||||
<Compile Include="Interfaces\IRecentItem.cs" />
|
<Compile Include="Interfaces\IRecentItem.cs" />
|
||||||
<Compile Include="Interfaces\IResource.cs" />
|
<Compile Include="Interfaces\IResourceService.cs" />
|
||||||
<Compile Include="ViewModels\DonateVm.cs" />
|
<Compile Include="Services\SingletonServiceBase.cs" />
|
||||||
|
<Compile Include="TemplateSelectors\SelectableDataTemplateSelector.cs" />
|
||||||
|
<Compile Include="ViewModels\Items\SettingsSaveVm.cs" />
|
||||||
<Compile Include="Views\MainPageFrames\DonatePage.xaml.cs">
|
<Compile Include="Views\MainPageFrames\DonatePage.xaml.cs">
|
||||||
<DependentUpon>DonatePage.xaml</DependentUpon>
|
<DependentUpon>DonatePage.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Services\DatabaseService.cs" />
|
<Compile Include="Services\DatabaseService.cs" />
|
||||||
<Compile Include="Interfaces\ISettings.cs" />
|
<Compile Include="Interfaces\ISettingsService.cs" />
|
||||||
<Compile Include="Common\MessageDialogHelper.cs" />
|
<Compile Include="Common\MessageDialogHelper.cs" />
|
||||||
<Compile Include="Common\NavigationHelper.cs" />
|
<Compile Include="Common\NavigationHelper.cs" />
|
||||||
<Compile Include="Common\NotifyPropertyChangedBase.cs" />
|
<Compile Include="Common\NotifyPropertyChangedBase.cs" />
|
||||||
@@ -139,7 +146,7 @@
|
|||||||
<Compile Include="Converters\NullToBooleanConverter.cs" />
|
<Compile Include="Converters\NullToBooleanConverter.cs" />
|
||||||
<Compile Include="Exceptions\SaveException.cs" />
|
<Compile Include="Exceptions\SaveException.cs" />
|
||||||
<Compile Include="Extensions\DispatcherTaskExtensions.cs" />
|
<Compile Include="Extensions\DispatcherTaskExtensions.cs" />
|
||||||
<Compile Include="Interfaces\IDatabase.cs" />
|
<Compile Include="Interfaces\IDatabaseService.cs" />
|
||||||
<Compile Include="Interfaces\IHasSelectableObject.cs" />
|
<Compile Include="Interfaces\IHasSelectableObject.cs" />
|
||||||
<Compile Include="Interfaces\ISelectableModel.cs" />
|
<Compile Include="Interfaces\ISelectableModel.cs" />
|
||||||
<Compile Include="Views\BasePages\LayoutAwarePageBase.cs" />
|
<Compile Include="Views\BasePages\LayoutAwarePageBase.cs" />
|
||||||
@@ -149,6 +156,9 @@
|
|||||||
<Compile Include="Views\SettingsPageFrames\SettingsNewDatabasePage.xaml.cs">
|
<Compile Include="Views\SettingsPageFrames\SettingsNewDatabasePage.xaml.cs">
|
||||||
<DependentUpon>SettingsNewDatabasePage.xaml</DependentUpon>
|
<DependentUpon>SettingsNewDatabasePage.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Views\SettingsPageFrames\SettingsSavePage.xaml.cs">
|
||||||
|
<DependentUpon>SettingsSavePage.xaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="Views\SettingsPageFrames\SettingsSecurityPage.xaml.cs">
|
<Compile Include="Views\SettingsPageFrames\SettingsSecurityPage.xaml.cs">
|
||||||
<DependentUpon>SettingsSecurityPage.xaml</DependentUpon>
|
<DependentUpon>SettingsSecurityPage.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
@@ -165,7 +175,6 @@
|
|||||||
<Compile Include="Converters\ColorToBrushConverter.cs" />
|
<Compile Include="Converters\ColorToBrushConverter.cs" />
|
||||||
<Compile Include="Converters\DoubleToSolidColorBrushConverter.cs" />
|
<Compile Include="Converters\DoubleToSolidColorBrushConverter.cs" />
|
||||||
<Compile Include="Converters\InverseBooleanToVisibilityConverter.cs" />
|
<Compile Include="Converters\InverseBooleanToVisibilityConverter.cs" />
|
||||||
<Compile Include="Converters\BooleanToFontStyleConverter.cs" />
|
|
||||||
<Compile Include="Converters\PluralizationConverter.cs" />
|
<Compile Include="Converters\PluralizationConverter.cs" />
|
||||||
<Compile Include="Converters\ProgressBarLegalValuesConverter.cs" />
|
<Compile Include="Converters\ProgressBarLegalValuesConverter.cs" />
|
||||||
<Compile Include="Converters\TextToWidthConverter.cs" />
|
<Compile Include="Converters\TextToWidthConverter.cs" />
|
||||||
@@ -240,6 +249,10 @@
|
|||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</ApplicationDefinition>
|
</ApplicationDefinition>
|
||||||
|
<Page Include="Views\SettingsPageFrames\SettingsSavePage.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
<Page Include="Views\UserControls\CompositeKeyUserControl.xaml">
|
<Page Include="Views\UserControls\CompositeKeyUserControl.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
@@ -335,12 +348,24 @@
|
|||||||
<HintPath>..\packages\Portable.BouncyCastle.1.8.1.3\lib\netstandard1.0\BouncyCastle.Crypto.dll</HintPath>
|
<HintPath>..\packages\Portable.BouncyCastle.1.8.1.3\lib\netstandard1.0\BouncyCastle.Crypto.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.AppCenter, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\Microsoft.AppCenter.1.5.0\lib\portable-net45+win8+wpa81+wp8\Microsoft.AppCenter.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.AppCenter.Analytics, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\Microsoft.AppCenter.Analytics.1.5.0\lib\portable-net45+win8+wpa81+wp8\Microsoft.AppCenter.Analytics.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.AppCenter.Push, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\Microsoft.AppCenter.Push.1.5.0\lib\portable-net45+win8+wpa81+wp8\Microsoft.AppCenter.Push.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
<Reference Include="Microsoft.Toolkit.Uwp.Notifications, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="Microsoft.Toolkit.Uwp.Notifications, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\Microsoft.Toolkit.Uwp.Notifications.2.0.0\lib\dotnet\Microsoft.Toolkit.Uwp.Notifications.dll</HintPath>
|
<HintPath>..\packages\Microsoft.Toolkit.Uwp.Notifications.2.0.0\lib\dotnet\Microsoft.Toolkit.Uwp.Notifications.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="ModernKeePassLib, Version=2.37.0.2000, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="ModernKeePassLib, Version=2.37.0.2000, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\ModernKeePassLib.2.37.8000\lib\netstandard1.2\ModernKeePassLib.dll</HintPath>
|
<HintPath>..\packages\ModernKeePassLib.2.38.2\lib\netstandard1.2\ModernKeePassLib.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Splat, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="Splat, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
@@ -434,9 +459,6 @@
|
|||||||
<Content Include="Assets\Wide310x150Logo.scale-140.png" />
|
<Content Include="Assets\Wide310x150Logo.scale-140.png" />
|
||||||
<Content Include="Assets\Wide310x150Logo.scale-180.png" />
|
<Content Include="Assets\Wide310x150Logo.scale-180.png" />
|
||||||
<Content Include="Assets\Wide310x150Logo.scale-80.png" />
|
<Content Include="Assets\Wide310x150Logo.scale-80.png" />
|
||||||
<Content Include="Data\WindowsStoreProxy.xml">
|
|
||||||
<SubType>Designer</SubType>
|
|
||||||
</Content>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '12.0' ">
|
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '12.0' ">
|
||||||
<VisualStudioVersion>12.0</VisualStudioVersion>
|
<VisualStudioVersion>12.0</VisualStudioVersion>
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest" xmlns:m2="http://schemas.microsoft.com/appx/2013/manifest">
|
<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest" xmlns:m2="http://schemas.microsoft.com/appx/2013/manifest">
|
||||||
<Identity Name="wismna.ModernKeePass" Publisher="CN=0719A91A-C322-4EE0-A257-E60733EECF06" Version="1.10.0.31" />
|
<Identity Name="wismna.ModernKeePass" Publisher="CN=0719A91A-C322-4EE0-A257-E60733EECF06" Version="1.13.0.32" />
|
||||||
<Properties>
|
<Properties>
|
||||||
<DisplayName>ModernKeePass</DisplayName>
|
<DisplayName>ModernKeePass</DisplayName>
|
||||||
<PublisherDisplayName>wismna</PublisherDisplayName>
|
<PublisherDisplayName>wismna</PublisherDisplayName>
|
||||||
|
@@ -24,6 +24,6 @@ using System.Runtime.InteropServices;
|
|||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("1.10.0.0")]
|
[assembly: AssemblyVersion("1.13.0.0")]
|
||||||
[assembly: AssemblyFileVersion("1.10.0.0")]
|
[assembly: AssemblyFileVersion("1.13.0.0")]
|
||||||
[assembly: ComVisible(false)]
|
[assembly: ComVisible(false)]
|
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Windows.Storage;
|
using Windows.Storage;
|
||||||
using Windows.UI.Xaml.Controls;
|
using Windows.UI.Xaml.Controls;
|
||||||
using ModernKeePass.Exceptions;
|
using ModernKeePass.Exceptions;
|
||||||
@@ -14,22 +15,14 @@ using ModernKeePassLib.Serialization;
|
|||||||
|
|
||||||
namespace ModernKeePass.Services
|
namespace ModernKeePass.Services
|
||||||
{
|
{
|
||||||
public class DatabaseService: IDatabase
|
public class DatabaseService: SingletonServiceBase<DatabaseService>, IDatabaseService
|
||||||
{
|
{
|
||||||
public enum DatabaseStatus
|
|
||||||
{
|
|
||||||
Error = -3,
|
|
||||||
NoCompositeKey = -2,
|
|
||||||
CompositeKeyError = -1,
|
|
||||||
Closed = 0,
|
|
||||||
Opening = 1,
|
|
||||||
Opened = 2
|
|
||||||
}
|
|
||||||
private readonly PwDatabase _pwDatabase = new PwDatabase();
|
private readonly PwDatabase _pwDatabase = new PwDatabase();
|
||||||
private readonly ISettings _settings;
|
private readonly ISettingsService _settings;
|
||||||
private readonly IResource _resource;
|
private StorageFile _realDatabaseFile;
|
||||||
private StorageFile _databaseFile;
|
private StorageFile _databaseFile;
|
||||||
private GroupVm _recycleBin;
|
private GroupVm _recycleBin;
|
||||||
|
private CompositeKey _compositeKey;
|
||||||
|
|
||||||
public GroupVm RootGroup { get; set; }
|
public GroupVm RootGroup { get; set; }
|
||||||
|
|
||||||
@@ -39,11 +32,10 @@ namespace ModernKeePass.Services
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
_recycleBin = value;
|
_recycleBin = value;
|
||||||
_pwDatabase.RecycleBinUuid = _recycleBin.IdUuid;
|
_pwDatabase.RecycleBinUuid = _recycleBin?.IdUuid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Status { get; set; } = (int)DatabaseStatus.Closed;
|
|
||||||
public string Name => DatabaseFile?.Name;
|
public string Name => DatabaseFile?.Name;
|
||||||
|
|
||||||
public bool RecycleBinEnabled
|
public bool RecycleBinEnabled
|
||||||
@@ -57,9 +49,18 @@ namespace ModernKeePass.Services
|
|||||||
get { return _databaseFile; }
|
get { return _databaseFile; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_databaseFile = value;
|
if (IsOpen && HasChanged)
|
||||||
Status = (int)DatabaseStatus.Opening;
|
{
|
||||||
|
throw new DatabaseOpenedException();
|
||||||
}
|
}
|
||||||
|
_databaseFile = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompositeKey CompositeKey
|
||||||
|
{
|
||||||
|
get { return _compositeKey; }
|
||||||
|
set { _compositeKey = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public PwUuid DataCipher
|
public PwUuid DataCipher
|
||||||
@@ -80,29 +81,38 @@ namespace ModernKeePass.Services
|
|||||||
set { _pwDatabase.KdfParameters = value; }
|
set { _pwDatabase.KdfParameters = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public DatabaseService() : this(new SettingsService())
|
public bool IsOpen => _pwDatabase.IsOpen;
|
||||||
{ }
|
public bool IsFileOpen => !_pwDatabase.IsOpen && _databaseFile != null;
|
||||||
|
public bool IsClosed => _databaseFile == null;
|
||||||
|
public bool HasChanged { get; set; }
|
||||||
|
|
||||||
public DatabaseService(ISettings settings)
|
public DatabaseService() : this(SettingsService.Instance)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public DatabaseService(ISettingsService settings)
|
||||||
{
|
{
|
||||||
_settings = settings;
|
_settings = settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Open a KeePass database
|
/// Open a KeePass database
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="key">The database composite key</param>
|
/// <param name="key">The database composite key</param>
|
||||||
/// <param name="createNew">True to create a new database before opening it</param>
|
/// <param name="createNew">True to create a new database before opening it</param>
|
||||||
/// <returns>An error message, if any</returns>
|
/// <returns>An error message, if any</returns>
|
||||||
public void Open(CompositeKey key, bool createNew = false)
|
public async Task Open(CompositeKey key, bool createNew = false)
|
||||||
{
|
{
|
||||||
|
// TODO: Check if there is an existing backup file
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (key == null)
|
if (key == null)
|
||||||
{
|
{
|
||||||
Status = (int)DatabaseStatus.NoCompositeKey;
|
throw new ArgumentNullException(nameof(key));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_compositeKey = key;
|
||||||
var ioConnection = IOConnectionInfo.FromFile(DatabaseFile);
|
var ioConnection = IOConnectionInfo.FromFile(DatabaseFile);
|
||||||
if (createNew)
|
if (createNew)
|
||||||
{
|
{
|
||||||
@@ -120,18 +130,50 @@ namespace ModernKeePass.Services
|
|||||||
}
|
}
|
||||||
else _pwDatabase.Open(ioConnection, key, new NullStatusLogger());
|
else _pwDatabase.Open(ioConnection, key, new NullStatusLogger());
|
||||||
|
|
||||||
if (!_pwDatabase.IsOpen) return;
|
//if (!_pwDatabase.IsOpen) return;
|
||||||
Status = (int)DatabaseStatus.Opened;
|
|
||||||
|
// Copy database in temp directory and use this file for operations
|
||||||
|
if (_settings.GetSetting<bool>("AntiCorruption"))
|
||||||
|
{
|
||||||
|
_realDatabaseFile = _databaseFile;
|
||||||
|
var backupFile =
|
||||||
|
await ApplicationData.Current.RoamingFolder.CreateFileAsync(Name,
|
||||||
|
CreationCollisionOption.FailIfExists);
|
||||||
|
Save(backupFile);
|
||||||
|
}
|
||||||
|
|
||||||
RootGroup = new GroupVm(_pwDatabase.RootGroup, null, RecycleBinEnabled ? _pwDatabase.RecycleBinUuid : null);
|
RootGroup = new GroupVm(_pwDatabase.RootGroup, null, RecycleBinEnabled ? _pwDatabase.RecycleBinUuid : null);
|
||||||
}
|
}
|
||||||
catch (InvalidCompositeKeyException)
|
catch (InvalidCompositeKeyException ex)
|
||||||
{
|
{
|
||||||
Status = (int)DatabaseStatus.CompositeKeyError;
|
throw new ArgumentException(ex.Message, ex);
|
||||||
}
|
}
|
||||||
catch (Exception)
|
}
|
||||||
|
|
||||||
|
public async Task ReOpen()
|
||||||
{
|
{
|
||||||
Status = (int)DatabaseStatus.Error;
|
await Open(_compositeKey);
|
||||||
throw;
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Commit the changes to the currently opened database to file
|
||||||
|
/// </summary>
|
||||||
|
public void Save()
|
||||||
|
{
|
||||||
|
if (!IsOpen) return;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_pwDatabase.Save(new NullStatusLogger());
|
||||||
|
|
||||||
|
// Test if save worked correctly
|
||||||
|
if (_settings.GetSetting<bool>("AntiCorruption"))
|
||||||
|
{
|
||||||
|
_pwDatabase.Open(_pwDatabase.IOConnectionInfo, _pwDatabase.MasterKey, new NullStatusLogger());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new SaveException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,35 +194,23 @@ namespace ModernKeePass.Services
|
|||||||
DatabaseFile = oldFile;
|
DatabaseFile = oldFile;
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
Status = (int)DatabaseStatus.Opened;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Commit the changes to the currently opened database to file
|
|
||||||
/// </summary>
|
|
||||||
public void Save()
|
|
||||||
{
|
|
||||||
if (_pwDatabase == null || !_pwDatabase.IsOpen) return;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_pwDatabase.Save(new NullStatusLogger());
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
throw new SaveException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Close the currently opened database
|
/// Close the currently opened database
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Close()
|
public async Task Close(bool releaseFile = true)
|
||||||
{
|
{
|
||||||
_pwDatabase?.Close();
|
_pwDatabase?.Close();
|
||||||
Status = (int)DatabaseStatus.Closed;
|
|
||||||
|
// Restore the backup DB to the original one
|
||||||
|
if (_settings.GetSetting<bool>("AntiCorruption"))
|
||||||
|
{
|
||||||
|
if (_pwDatabase != null && _pwDatabase.Modified)
|
||||||
|
Save(_realDatabaseFile);
|
||||||
|
await DatabaseFile.DeleteAsync();
|
||||||
|
}
|
||||||
|
if (releaseFile) DatabaseFile = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddDeletedItem(PwUuid id)
|
public void AddDeletedItem(PwUuid id)
|
||||||
@@ -188,18 +218,13 @@ namespace ModernKeePass.Services
|
|||||||
_pwDatabase.DeletedObjects.Add(new PwDeletedObject(id, DateTime.UtcNow));
|
_pwDatabase.DeletedObjects.Add(new PwDeletedObject(id, DateTime.UtcNow));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CreateRecycleBin()
|
public void CreateRecycleBin(string title)
|
||||||
{
|
{
|
||||||
RecycleBin = RootGroup.AddNewGroup("Recycle bin");
|
RecycleBin = RootGroup.AddNewGroup(title);
|
||||||
RecycleBin.IsSelected = true;
|
RecycleBin.IsSelected = true;
|
||||||
RecycleBin.IconSymbol = Symbol.Delete;
|
RecycleBin.IconSymbol = Symbol.Delete;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateCompositeKey(CompositeKey key)
|
|
||||||
{
|
|
||||||
_pwDatabase.MasterKey = key;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CreateSampleData()
|
private void CreateSampleData()
|
||||||
{
|
{
|
||||||
_pwDatabase.RootGroup.AddGroup(new PwGroup(true, true, "Banking", PwIcon.Count), true);
|
_pwDatabase.RootGroup.AddGroup(new PwGroup(true, true, "Banking", PwIcon.Count), true);
|
||||||
|
@@ -1,13 +1,12 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Windows.ApplicationModel;
|
|
||||||
using Windows.ApplicationModel.Store;
|
using Windows.ApplicationModel.Store;
|
||||||
using ModernKeePass.Interfaces;
|
using ModernKeePass.Interfaces;
|
||||||
|
|
||||||
namespace ModernKeePass.Services
|
namespace ModernKeePass.Services
|
||||||
{
|
{
|
||||||
public class LicenseService : ILicenseService
|
public class LicenseService : SingletonServiceBase<LicenseService>, ILicenseService
|
||||||
{
|
{
|
||||||
public enum PurchaseResult
|
public enum PurchaseResult
|
||||||
{
|
{
|
||||||
@@ -27,34 +26,13 @@ namespace ModernKeePass.Services
|
|||||||
|
|
||||||
public LicenseService()
|
public LicenseService()
|
||||||
{
|
{
|
||||||
// Initialize the license info for use in the app that is uploaded to the Store.
|
|
||||||
// Uncomment the following line in the release version of your app.
|
|
||||||
//_licenseInformation = CurrentApp.LicenseInformation;
|
|
||||||
|
|
||||||
// Initialize the license info for testing.
|
|
||||||
// Comment the following line in the release version of your app.
|
|
||||||
//_licenseInformation = CurrentAppSimulator.LicenseInformation;
|
|
||||||
#if DEBUG
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var proxyFile = Package.Current.InstalledLocation.GetFileAsync("data\\WindowsStoreProxy.xml").GetAwaiter().GetResult();
|
|
||||||
CurrentAppSimulator.ReloadSimulatorAsync(proxyFile).GetAwaiter().GetResult();
|
|
||||||
}
|
|
||||||
catch { }
|
|
||||||
var listing = CurrentAppSimulator.LoadListingInformationAsync().GetAwaiter().GetResult();
|
|
||||||
#else
|
|
||||||
var listing = CurrentApp.LoadListingInformationAsync().GetAwaiter().GetResult();
|
var listing = CurrentApp.LoadListingInformationAsync().GetAwaiter().GetResult();
|
||||||
#endif
|
|
||||||
Products = listing.ProductListings;
|
Products = listing.ProductListings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> Purchase(string addOn)
|
public async Task<int> Purchase(string addOn)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
|
||||||
var purchaseResults = await CurrentAppSimulator.RequestProductPurchaseAsync(addOn);
|
|
||||||
#else
|
|
||||||
var purchaseResults = await CurrentApp.RequestProductPurchaseAsync(addOn);
|
var purchaseResults = await CurrentApp.RequestProductPurchaseAsync(addOn);
|
||||||
#endif
|
|
||||||
switch (purchaseResults.Status)
|
switch (purchaseResults.Status)
|
||||||
{
|
{
|
||||||
case ProductPurchaseStatus.Succeeded:
|
case ProductPurchaseStatus.Succeeded:
|
||||||
@@ -79,11 +57,7 @@ namespace ModernKeePass.Services
|
|||||||
|
|
||||||
private async Task<PurchaseResult> ReportFulfillmentAsync(Guid transactionId, string productName)
|
private async Task<PurchaseResult> ReportFulfillmentAsync(Guid transactionId, string productName)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
|
||||||
var result = await CurrentAppSimulator.ReportConsumableFulfillmentAsync(productName, transactionId);
|
|
||||||
#else
|
|
||||||
var result = await CurrentApp.ReportConsumableFulfillmentAsync(productName, transactionId);
|
var result = await CurrentApp.ReportConsumableFulfillmentAsync(productName, transactionId);
|
||||||
#endif
|
|
||||||
return (PurchaseResult) result;
|
return (PurchaseResult) result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -8,7 +8,7 @@ using ModernKeePass.ViewModels;
|
|||||||
|
|
||||||
namespace ModernKeePass.Services
|
namespace ModernKeePass.Services
|
||||||
{
|
{
|
||||||
public class RecentService : IRecent
|
public class RecentService : SingletonServiceBase<RecentService>, IRecentService
|
||||||
{
|
{
|
||||||
private readonly StorageItemMostRecentlyUsedList _mru = StorageApplicationPermissions.MostRecentlyUsedList;
|
private readonly StorageItemMostRecentlyUsedList _mru = StorageApplicationPermissions.MostRecentlyUsedList;
|
||||||
|
|
||||||
|
@@ -3,7 +3,7 @@ using ModernKeePass.Interfaces;
|
|||||||
|
|
||||||
namespace ModernKeePass.Services
|
namespace ModernKeePass.Services
|
||||||
{
|
{
|
||||||
public class ResourcesService: IResource
|
public class ResourcesService: IResourceService
|
||||||
{
|
{
|
||||||
private const string ResourceFileName = "CodeBehind";
|
private const string ResourceFileName = "CodeBehind";
|
||||||
private readonly ResourceLoader _resourceLoader = ResourceLoader.GetForCurrentView();
|
private readonly ResourceLoader _resourceLoader = ResourceLoader.GetForCurrentView();
|
||||||
|
@@ -5,11 +5,11 @@ using ModernKeePass.Interfaces;
|
|||||||
|
|
||||||
namespace ModernKeePass.Services
|
namespace ModernKeePass.Services
|
||||||
{
|
{
|
||||||
public class SettingsService : ISettings
|
public class SettingsService : SingletonServiceBase<SettingsService>, ISettingsService
|
||||||
{
|
{
|
||||||
private readonly IPropertySet _values = ApplicationData.Current.LocalSettings.Values;
|
private readonly IPropertySet _values = ApplicationData.Current.LocalSettings.Values;
|
||||||
|
|
||||||
public T GetSetting<T>(string property)
|
public T GetSetting<T>(string property, T defaultValue = default(T))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -17,7 +17,7 @@ namespace ModernKeePass.Services
|
|||||||
}
|
}
|
||||||
catch (InvalidCastException)
|
catch (InvalidCastException)
|
||||||
{
|
{
|
||||||
return default(T);
|
return defaultValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
ModernKeePass/Services/SingletonServiceBase.cs
Normal file
12
ModernKeePass/Services/SingletonServiceBase.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace ModernKeePass.Services
|
||||||
|
{
|
||||||
|
public abstract class SingletonServiceBase<T> where T : new()
|
||||||
|
{
|
||||||
|
private static readonly Lazy<T> LazyInstance =
|
||||||
|
new Lazy<T>(() => new T());
|
||||||
|
|
||||||
|
public static T Instance => LazyInstance.Value;
|
||||||
|
}
|
||||||
|
}
|
@@ -204,9 +204,6 @@
|
|||||||
<data name="EntryDeletingConfirmation" xml:space="preserve">
|
<data name="EntryDeletingConfirmation" xml:space="preserve">
|
||||||
<value>Are you sure you want to delete this entry?</value>
|
<value>Are you sure you want to delete this entry?</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="EntryNew" xml:space="preserve">
|
|
||||||
<value>< New entry ></value>
|
|
||||||
</data>
|
|
||||||
<data name="EntryRecycled" xml:space="preserve">
|
<data name="EntryRecycled" xml:space="preserve">
|
||||||
<value>Entry moved to the Recycle bin</value>
|
<value>Entry moved to the Recycle bin</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -222,9 +219,6 @@
|
|||||||
<data name="GroupDeletingConfirmation" xml:space="preserve">
|
<data name="GroupDeletingConfirmation" xml:space="preserve">
|
||||||
<value>Are you sure you want to delete the whole group and all its entries?</value>
|
<value>Are you sure you want to delete the whole group and all its entries?</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="GroupNew" xml:space="preserve">
|
|
||||||
<value>< New group ></value>
|
|
||||||
</data>
|
|
||||||
<data name="GroupRecycled" xml:space="preserve">
|
<data name="GroupRecycled" xml:space="preserve">
|
||||||
<value>Group moved to the Recycle bin</value>
|
<value>Group moved to the Recycle bin</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -270,4 +264,13 @@
|
|||||||
<data name="SettingsMenuItemSecurity" xml:space="preserve">
|
<data name="SettingsMenuItemSecurity" xml:space="preserve">
|
||||||
<value>Security</value>
|
<value>Security</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="CompositeKeyErrorUserAccount" xml:space="preserve">
|
||||||
|
<value>user account</value>
|
||||||
|
</data>
|
||||||
|
<data name="SettingsMenuItemSave" xml:space="preserve">
|
||||||
|
<value>Saving</value>
|
||||||
|
</data>
|
||||||
|
<data name="RecycleBinTitle" xml:space="preserve">
|
||||||
|
<value>Recycle Bin</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@@ -171,11 +171,14 @@
|
|||||||
<data name="CompositeKeyPassword.PlaceholderText" xml:space="preserve">
|
<data name="CompositeKeyPassword.PlaceholderText" xml:space="preserve">
|
||||||
<value>Password</value>
|
<value>Password</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="CompositeKeyUserAccount.Text" xml:space="preserve">
|
||||||
|
<value>Windows User Account</value>
|
||||||
|
</data>
|
||||||
<data name="DonateButton.Content" xml:space="preserve">
|
<data name="DonateButton.Content" xml:space="preserve">
|
||||||
<value>Donate</value>
|
<value>Donate</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="DonateDesc.Text" xml:space="preserve">
|
<data name="DonateDesc.Text" xml:space="preserve">
|
||||||
<value>Like this app? Why not make a small donation to support my work and help this app stay ad-free :) ?</value>
|
<value>Like this app? Why not make a small donation to support my work and help me keep it ad-free :) ?</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="EntryExpirationDate.Content" xml:space="preserve">
|
<data name="EntryExpirationDate.Content" xml:space="preserve">
|
||||||
<value>Expiration date</value>
|
<value>Expiration date</value>
|
||||||
@@ -183,6 +186,15 @@
|
|||||||
<data name="EntryExpirationTooltip.Content" xml:space="preserve">
|
<data name="EntryExpirationTooltip.Content" xml:space="preserve">
|
||||||
<value>Password has expired</value>
|
<value>Password has expired</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="EntryItemCopyLogin.Text" xml:space="preserve">
|
||||||
|
<value>Copy login</value>
|
||||||
|
</data>
|
||||||
|
<data name="EntryItemCopyPassword.Text" xml:space="preserve">
|
||||||
|
<value>Copy password</value>
|
||||||
|
</data>
|
||||||
|
<data name="EntryItemCopyUrl.Text" xml:space="preserve">
|
||||||
|
<value>Navigate to URL</value>
|
||||||
|
</data>
|
||||||
<data name="EntryLogin.Text" xml:space="preserve">
|
<data name="EntryLogin.Text" xml:space="preserve">
|
||||||
<value>User name or login</value>
|
<value>User name or login</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -202,10 +214,10 @@
|
|||||||
<value>Filter...</value>
|
<value>Filter...</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="GroupNewItemTextBox.Text" xml:space="preserve">
|
<data name="GroupNewItemTextBox.Text" xml:space="preserve">
|
||||||
<value>< New group ></value>
|
<value>New group</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="GroupNewItemTooltip.Content" xml:space="preserve">
|
<data name="GroupNewItemTooltip.Content" xml:space="preserve">
|
||||||
<value>< New group ></value>
|
<value>New group</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="GroupSearch.PlaceholderText" xml:space="preserve">
|
<data name="GroupSearch.PlaceholderText" xml:space="preserve">
|
||||||
<value>Search...</value>
|
<value>Search...</value>
|
||||||
@@ -270,6 +282,9 @@
|
|||||||
<data name="RecentClear.Text" xml:space="preserve">
|
<data name="RecentClear.Text" xml:space="preserve">
|
||||||
<value>Clear all</value>
|
<value>Clear all</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="ReorderEntriesLabel.Text" xml:space="preserve">
|
||||||
|
<value>Drag and drop entries to reorder them</value>
|
||||||
|
</data>
|
||||||
<data name="SaveAsButton.Content" xml:space="preserve">
|
<data name="SaveAsButton.Content" xml:space="preserve">
|
||||||
<value>Save as...</value>
|
<value>Save as...</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -300,6 +315,12 @@
|
|||||||
<data name="SettingsDatabaseRecycleBin.OnContent" xml:space="preserve">
|
<data name="SettingsDatabaseRecycleBin.OnContent" xml:space="preserve">
|
||||||
<value>Enabled</value>
|
<value>Enabled</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="SettingsDatabaseRecycleBinCreate.Content" xml:space="preserve">
|
||||||
|
<value>Create a new group</value>
|
||||||
|
</data>
|
||||||
|
<data name="SettingsDatabaseRecycleBinExisting.Content" xml:space="preserve">
|
||||||
|
<value>Use an existing group</value>
|
||||||
|
</data>
|
||||||
<data name="SettingsNewDatabaseDesc.Text" xml:space="preserve">
|
<data name="SettingsNewDatabaseDesc.Text" xml:space="preserve">
|
||||||
<value>Here, you can change some default options when creating a database.</value>
|
<value>Here, you can change some default options when creating a database.</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -318,6 +339,18 @@
|
|||||||
<data name="SettingsNewDatabaseSample.OnContent" xml:space="preserve">
|
<data name="SettingsNewDatabaseSample.OnContent" xml:space="preserve">
|
||||||
<value>Yes</value>
|
<value>Yes</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="SettingsSaveDatabaseSuspend.OffContent" xml:space="preserve">
|
||||||
|
<value>Don't save</value>
|
||||||
|
</data>
|
||||||
|
<data name="SettingsSaveDatabaseSuspend.OnContent" xml:space="preserve">
|
||||||
|
<value>Save</value>
|
||||||
|
</data>
|
||||||
|
<data name="SettingsSaveDatabaseSuspendDesc.Text" xml:space="preserve">
|
||||||
|
<value>This settings is generally recommended. If you enable it, database will automatically be saved on application suspension and closing. However, if your database is huge, saving may be deemed too long by Windows, which will then forcibly kill the app.</value>
|
||||||
|
</data>
|
||||||
|
<data name="SettingsSaveDatabaseSuspendTitle.Text" xml:space="preserve">
|
||||||
|
<value>Auto-save on suspend?</value>
|
||||||
|
</data>
|
||||||
<data name="SettingsSecurityDesc1.Text" xml:space="preserve">
|
<data name="SettingsSecurityDesc1.Text" xml:space="preserve">
|
||||||
<value>Here, you may change your database password, key file, or both. Just click on on</value>
|
<value>Here, you may change your database password, key file, or both. Just click on on</value>
|
||||||
</data>
|
</data>
|
||||||
|
@@ -204,10 +204,6 @@
|
|||||||
<data name="EntryDeletingConfirmation" xml:space="preserve">
|
<data name="EntryDeletingConfirmation" xml:space="preserve">
|
||||||
<value>Êtes-vous sûr de vouloir supprimer cette entrée ?</value>
|
<value>Êtes-vous sûr de vouloir supprimer cette entrée ?</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="EntryNew" xml:space="preserve">
|
|
||||||
<value>< Nouvelle entrée ></value>
|
|
||||||
<comment>Unused</comment>
|
|
||||||
</data>
|
|
||||||
<data name="EntryRecycled" xml:space="preserve">
|
<data name="EntryRecycled" xml:space="preserve">
|
||||||
<value>Entrée placée dans la Corbeille</value>
|
<value>Entrée placée dans la Corbeille</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -223,9 +219,6 @@
|
|||||||
<data name="GroupDeletingConfirmation" xml:space="preserve">
|
<data name="GroupDeletingConfirmation" xml:space="preserve">
|
||||||
<value>Êtes-vous sûr de vouloir supprimer ce group et toutes ses entrées ?</value>
|
<value>Êtes-vous sûr de vouloir supprimer ce group et toutes ses entrées ?</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="GroupNew" xml:space="preserve">
|
|
||||||
<value>< Nouveau groupe ></value>
|
|
||||||
</data>
|
|
||||||
<data name="GroupRecycled" xml:space="preserve">
|
<data name="GroupRecycled" xml:space="preserve">
|
||||||
<value>Groupe placé dans la Corbeille</value>
|
<value>Groupe placé dans la Corbeille</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -271,4 +264,13 @@
|
|||||||
<data name="SettingsMenuItemSecurity" xml:space="preserve">
|
<data name="SettingsMenuItemSecurity" xml:space="preserve">
|
||||||
<value>Sécurité</value>
|
<value>Sécurité</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="CompositeKeyErrorUserAccount" xml:space="preserve">
|
||||||
|
<value>compte utilisateur</value>
|
||||||
|
</data>
|
||||||
|
<data name="SettingsMenuItemSave" xml:space="preserve">
|
||||||
|
<value>Sauvegardes</value>
|
||||||
|
</data>
|
||||||
|
<data name="RecycleBinTitle" xml:space="preserve">
|
||||||
|
<value>Corbeille</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@@ -142,7 +142,7 @@
|
|||||||
<value>Accueil</value>
|
<value>Accueil</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="AppBarRestore.Label" xml:space="preserve">
|
<data name="AppBarRestore.Label" xml:space="preserve">
|
||||||
<value>Restorer</value>
|
<value>Restaurer</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="AppBarSave.Label" xml:space="preserve">
|
<data name="AppBarSave.Label" xml:space="preserve">
|
||||||
<value>Sauvegarder</value>
|
<value>Sauvegarder</value>
|
||||||
@@ -171,6 +171,9 @@
|
|||||||
<data name="CompositeKeyPassword.PlaceholderText" xml:space="preserve">
|
<data name="CompositeKeyPassword.PlaceholderText" xml:space="preserve">
|
||||||
<value>Mot de passe</value>
|
<value>Mot de passe</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="CompositeKeyUserAccount.Text" xml:space="preserve">
|
||||||
|
<value>Compte Utilisateur Windows</value>
|
||||||
|
</data>
|
||||||
<data name="DonateButton.Content" xml:space="preserve">
|
<data name="DonateButton.Content" xml:space="preserve">
|
||||||
<value>Donner</value>
|
<value>Donner</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -183,6 +186,15 @@
|
|||||||
<data name="EntryExpirationTooltip.Content" xml:space="preserve">
|
<data name="EntryExpirationTooltip.Content" xml:space="preserve">
|
||||||
<value>Le mot de passe a expiré</value>
|
<value>Le mot de passe a expiré</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="EntryItemCopyLogin.Text" xml:space="preserve">
|
||||||
|
<value>Copier le login</value>
|
||||||
|
</data>
|
||||||
|
<data name="EntryItemCopyPassword.Text" xml:space="preserve">
|
||||||
|
<value>Copier le mot de passe</value>
|
||||||
|
</data>
|
||||||
|
<data name="EntryItemCopyUrl.Text" xml:space="preserve">
|
||||||
|
<value>Naviguer vers l'URL</value>
|
||||||
|
</data>
|
||||||
<data name="EntryLogin.Text" xml:space="preserve">
|
<data name="EntryLogin.Text" xml:space="preserve">
|
||||||
<value>Nom d'utilisateur ou login</value>
|
<value>Nom d'utilisateur ou login</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -202,10 +214,10 @@
|
|||||||
<value>Filtrer...</value>
|
<value>Filtrer...</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="GroupNewItemTextBox.Text" xml:space="preserve">
|
<data name="GroupNewItemTextBox.Text" xml:space="preserve">
|
||||||
<value>< Nouveau groupe ></value>
|
<value>Nouveau groupe</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="GroupNewItemTooltip.Content" xml:space="preserve">
|
<data name="GroupNewItemTooltip.Content" xml:space="preserve">
|
||||||
<value>< Nouveau groupe ></value>
|
<value>Nouveau groupe</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="GroupSearch.PlaceholderText" xml:space="preserve">
|
<data name="GroupSearch.PlaceholderText" xml:space="preserve">
|
||||||
<value>Rechercher...</value>
|
<value>Rechercher...</value>
|
||||||
@@ -270,6 +282,9 @@
|
|||||||
<data name="RecentClear.Text" xml:space="preserve">
|
<data name="RecentClear.Text" xml:space="preserve">
|
||||||
<value>Supprimer tout</value>
|
<value>Supprimer tout</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="ReorderEntriesLabel.Text" xml:space="preserve">
|
||||||
|
<value>Glissez-déposez les entrées pour les réorganiser</value>
|
||||||
|
</data>
|
||||||
<data name="SaveAsButton.Content" xml:space="preserve">
|
<data name="SaveAsButton.Content" xml:space="preserve">
|
||||||
<value>Sauvegarder sous...</value>
|
<value>Sauvegarder sous...</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -300,6 +315,12 @@
|
|||||||
<data name="SettingsDatabaseRecycleBin.OnContent" xml:space="preserve">
|
<data name="SettingsDatabaseRecycleBin.OnContent" xml:space="preserve">
|
||||||
<value>Activé</value>
|
<value>Activé</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="SettingsDatabaseRecycleBinCreate.Content" xml:space="preserve">
|
||||||
|
<value>Créer un nouveau groupe</value>
|
||||||
|
</data>
|
||||||
|
<data name="SettingsDatabaseRecycleBinExisting.Content" xml:space="preserve">
|
||||||
|
<value>Utiliser un groupe existant</value>
|
||||||
|
</data>
|
||||||
<data name="SettingsNewDatabaseDesc.Text" xml:space="preserve">
|
<data name="SettingsNewDatabaseDesc.Text" xml:space="preserve">
|
||||||
<value>Ici, vous pouvez changer certains options lors de la création d'une nouvelle base de données</value>
|
<value>Ici, vous pouvez changer certains options lors de la création d'une nouvelle base de données</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -318,6 +339,18 @@
|
|||||||
<data name="SettingsNewDatabaseSample.OnContent" xml:space="preserve">
|
<data name="SettingsNewDatabaseSample.OnContent" xml:space="preserve">
|
||||||
<value>Oui</value>
|
<value>Oui</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="SettingsSaveDatabaseSuspend.OffContent" xml:space="preserve">
|
||||||
|
<value>Ne pas sauvegarder</value>
|
||||||
|
</data>
|
||||||
|
<data name="SettingsSaveDatabaseSuspend.OnContent" xml:space="preserve">
|
||||||
|
<value>Sauvegarder</value>
|
||||||
|
</data>
|
||||||
|
<data name="SettingsSaveDatabaseSuspendDesc.Text" xml:space="preserve">
|
||||||
|
<value>Ce paramètre est généralement recommandé. Si vous l'activez, la base de données sera sauvegardée automatiquement lors de la suspension et de la fermeture. Cependant, si votre base de données est très volumineuse, il se peut que Windows estime que cela prend trop de temps et tue l'application.</value>
|
||||||
|
</data>
|
||||||
|
<data name="SettingsSaveDatabaseSuspendTitle.Text" xml:space="preserve">
|
||||||
|
<value>Sauvegarder automatiquement lors de la suspension ?</value>
|
||||||
|
</data>
|
||||||
<data name="SettingsSecurityDesc1.Text" xml:space="preserve">
|
<data name="SettingsSecurityDesc1.Text" xml:space="preserve">
|
||||||
<value>Ici, vous pouvez changer le mot de passe maître, le fichier de clé, ou les deux. Cliquez simplement sur</value>
|
<value>Ici, vous pouvez changer le mot de passe maître, le fichier de clé, ou les deux. Cliquez simplement sur</value>
|
||||||
</data>
|
</data>
|
||||||
|
@@ -0,0 +1,18 @@
|
|||||||
|
using Windows.UI.Xaml;
|
||||||
|
using Windows.UI.Xaml.Controls;
|
||||||
|
using ModernKeePass.Interfaces;
|
||||||
|
|
||||||
|
namespace ModernKeePass.TemplateSelectors
|
||||||
|
{
|
||||||
|
public class SelectableDataTemplateSelector: DataTemplateSelector
|
||||||
|
{
|
||||||
|
public DataTemplate TrueItem { get; set; }
|
||||||
|
public DataTemplate FalseItem { get; set; }
|
||||||
|
|
||||||
|
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
|
||||||
|
{
|
||||||
|
var isSelectableItem = item as ISelectableModel;
|
||||||
|
return isSelectableItem != null && isSelectableItem.IsSelected ? TrueItem : FalseItem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -2,7 +2,6 @@
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Windows.Storage;
|
using Windows.Storage;
|
||||||
using Windows.UI.Xaml;
|
|
||||||
using ModernKeePass.Common;
|
using ModernKeePass.Common;
|
||||||
using ModernKeePass.Interfaces;
|
using ModernKeePass.Interfaces;
|
||||||
using ModernKeePass.Services;
|
using ModernKeePass.Services;
|
||||||
@@ -22,7 +21,7 @@ namespace ModernKeePass.ViewModels
|
|||||||
Success = 5
|
Success = 5
|
||||||
}
|
}
|
||||||
|
|
||||||
public IDatabase Database { get; set; }
|
public IDatabaseService Database { get; set; }
|
||||||
|
|
||||||
public bool HasPassword
|
public bool HasPassword
|
||||||
{
|
{
|
||||||
@@ -44,7 +43,17 @@ namespace ModernKeePass.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsValid => !_isOpening && (HasPassword || HasKeyFile && KeyFile != null);
|
public bool HasUserAccount
|
||||||
|
{
|
||||||
|
get { return _hasUserAccount; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
SetProperty(ref _hasUserAccount, value);
|
||||||
|
OnPropertyChanged("IsValid");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsValid => !_isOpening && (HasPassword || HasKeyFile && KeyFile != null || HasUserAccount);
|
||||||
|
|
||||||
public string Status
|
public string Status
|
||||||
{
|
{
|
||||||
@@ -91,19 +100,21 @@ namespace ModernKeePass.ViewModels
|
|||||||
|
|
||||||
public double PasswordComplexityIndicator => QualityEstimation.EstimatePasswordBits(Password?.ToCharArray());
|
public double PasswordComplexityIndicator => QualityEstimation.EstimatePasswordBits(Password?.ToCharArray());
|
||||||
|
|
||||||
|
|
||||||
private bool _hasPassword;
|
private bool _hasPassword;
|
||||||
private bool _hasKeyFile;
|
private bool _hasKeyFile;
|
||||||
|
private bool _hasUserAccount;
|
||||||
private bool _isOpening;
|
private bool _isOpening;
|
||||||
private string _password = string.Empty;
|
private string _password = string.Empty;
|
||||||
private string _status;
|
private string _status;
|
||||||
private StatusTypes _statusType;
|
private StatusTypes _statusType;
|
||||||
private StorageFile _keyFile;
|
private StorageFile _keyFile;
|
||||||
private string _keyFileText;
|
private string _keyFileText;
|
||||||
private readonly IResource _resource;
|
private readonly IResourceService _resource;
|
||||||
|
|
||||||
public CompositeKeyVm() : this((Application.Current as App)?.Database, new ResourcesService()) { }
|
public CompositeKeyVm() : this(DatabaseService.Instance, new ResourcesService()) { }
|
||||||
|
|
||||||
public CompositeKeyVm(IDatabase database, IResource resource)
|
public CompositeKeyVm(IDatabaseService database, IResourceService resource)
|
||||||
{
|
{
|
||||||
_resource = resource;
|
_resource = resource;
|
||||||
_keyFileText = _resource.GetResourceValue("CompositeKeyDefaultKeyFile");
|
_keyFileText = _resource.GetResourceValue("CompositeKeyDefaultKeyFile");
|
||||||
@@ -112,42 +123,37 @@ namespace ModernKeePass.ViewModels
|
|||||||
|
|
||||||
public async Task<bool> OpenDatabase(bool createNew)
|
public async Task<bool> OpenDatabase(bool createNew)
|
||||||
{
|
{
|
||||||
var error = string.Empty;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_isOpening = true;
|
_isOpening = true;
|
||||||
Database.Open(CreateCompositeKey(), createNew);
|
await Database.Open(CreateCompositeKey(), createNew);
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
error = $"{_resource.GetResourceValue("CompositeKeyErrorOpen")}: {e.Message}";
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
_isOpening = false;
|
|
||||||
}
|
|
||||||
switch ((DatabaseService.DatabaseStatus)Database.Status)
|
|
||||||
{
|
|
||||||
case DatabaseService.DatabaseStatus.Opened:
|
|
||||||
await Task.Run(() => RootGroup = Database.RootGroup);
|
await Task.Run(() => RootGroup = Database.RootGroup);
|
||||||
return true;
|
return true;
|
||||||
case DatabaseService.DatabaseStatus.CompositeKeyError:
|
}
|
||||||
|
catch (ArgumentException)
|
||||||
|
{
|
||||||
var errorMessage = new StringBuilder(_resource.GetResourceValue("CompositeKeyErrorUserStart"));
|
var errorMessage = new StringBuilder(_resource.GetResourceValue("CompositeKeyErrorUserStart"));
|
||||||
if (HasPassword) errorMessage.Append(_resource.GetResourceValue("CompositeKeyErrorUserPassword"));
|
if (HasPassword) errorMessage.Append(_resource.GetResourceValue("CompositeKeyErrorUserPassword"));
|
||||||
if (HasPassword && HasKeyFile) errorMessage.Append(_resource.GetResourceValue("CompositeKeyErrorUserOr"));
|
if (HasPassword && HasKeyFile) errorMessage.Append(_resource.GetResourceValue("CompositeKeyErrorUserOr"));
|
||||||
if (HasKeyFile) errorMessage.Append(_resource.GetResourceValue("CompositeKeyErrorUserKeyFile"));
|
if (HasKeyFile) errorMessage.Append(_resource.GetResourceValue("CompositeKeyErrorUserKeyFile"));
|
||||||
|
if (HasUserAccount) errorMessage.Append(_resource.GetResourceValue("CompositeKeyErrorUserAccount"));
|
||||||
UpdateStatus(errorMessage.ToString(), StatusTypes.Error);
|
UpdateStatus(errorMessage.ToString(), StatusTypes.Error);
|
||||||
break;
|
}
|
||||||
case DatabaseService.DatabaseStatus.Error:
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
var error = $"{_resource.GetResourceValue("CompositeKeyErrorOpen")}: {e.Message}";
|
||||||
UpdateStatus(error, StatusTypes.Error);
|
UpdateStatus(error, StatusTypes.Error);
|
||||||
break;
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_isOpening = false;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateKey()
|
public void UpdateKey()
|
||||||
{
|
{
|
||||||
Database.UpdateCompositeKey(CreateCompositeKey());
|
Database.CompositeKey = CreateCompositeKey();
|
||||||
UpdateStatus(_resource.GetResourceValue("CompositeKeyUpdated"), StatusTypes.Success);
|
UpdateStatus(_resource.GetResourceValue("CompositeKeyUpdated"), StatusTypes.Success);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,6 +175,7 @@ namespace ModernKeePass.ViewModels
|
|||||||
var compositeKey = new CompositeKey();
|
var compositeKey = new CompositeKey();
|
||||||
if (HasPassword) compositeKey.AddUserKey(new KcpPassword(Password));
|
if (HasPassword) compositeKey.AddUserKey(new KcpPassword(Password));
|
||||||
if (HasKeyFile && KeyFile != null) compositeKey.AddUserKey(new KcpKeyFile(IOConnectionInfo.FromFile(KeyFile)));
|
if (HasKeyFile && KeyFile != null) compositeKey.AddUserKey(new KcpKeyFile(IOConnectionInfo.FromFile(KeyFile)));
|
||||||
|
if (HasUserAccount) compositeKey.AddUserKey(new KcpUserAccount());
|
||||||
return compositeKey;
|
return compositeKey;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,44 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using System.Globalization;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Windows.ApplicationModel.Store;
|
|
||||||
using ModernKeePass.Common;
|
|
||||||
using ModernKeePass.Interfaces;
|
|
||||||
using ModernKeePass.Services;
|
|
||||||
|
|
||||||
namespace ModernKeePass.ViewModels
|
|
||||||
{
|
|
||||||
public class DonateVm: NotifyPropertyChangedBase
|
|
||||||
{
|
|
||||||
public ObservableCollection<ProductListing> Donations { get; }
|
|
||||||
|
|
||||||
public ProductListing SelectedItem
|
|
||||||
{
|
|
||||||
get { return _selectedItem; }
|
|
||||||
set { SetProperty(ref _selectedItem, value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly ILicenseService _license;
|
|
||||||
private ProductListing _selectedItem;
|
|
||||||
|
|
||||||
public DonateVm() : this (new LicenseService()) { }
|
|
||||||
|
|
||||||
public DonateVm(ILicenseService license)
|
|
||||||
{
|
|
||||||
// TODO: find a nice way to order products
|
|
||||||
_license = license;
|
|
||||||
Donations = new ObservableCollection<ProductListing>(
|
|
||||||
_license.Products.Values
|
|
||||||
/*.OrderBy(p => decimal.Parse(p.FormattedPrice.Replace('\u00A0', ' '), NumberStyles.Currency,
|
|
||||||
CultureInfo.CurrentCulture.NumberFormat))*/
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<int> Purchase()
|
|
||||||
{
|
|
||||||
return await _license.Purchase(SelectedItem.ProductId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,8 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Windows.UI.Xaml;
|
|
||||||
using Windows.UI.Xaml.Controls;
|
using Windows.UI.Xaml.Controls;
|
||||||
|
using ModernKeePass.Attributes;
|
||||||
using ModernKeePass.Interfaces;
|
using ModernKeePass.Interfaces;
|
||||||
using ModernKeePass.Mappings;
|
using ModernKeePass.Mappings;
|
||||||
using ModernKeePass.Services;
|
using ModernKeePass.Services;
|
||||||
@@ -47,12 +47,7 @@ namespace ModernKeePass.ViewModels
|
|||||||
|
|
||||||
public string Name
|
public string Name
|
||||||
{
|
{
|
||||||
get
|
get { return GetEntryValue(PwDefs.TitleField); }
|
||||||
{
|
|
||||||
/*var title = GetEntryValue(PwDefs.TitleField);
|
|
||||||
return title == null ? _resource.GetResourceValue("EntryNew") : title;*/
|
|
||||||
return GetEntryValue(PwDefs.TitleField);
|
|
||||||
}
|
|
||||||
set { SetEntryValue(PwDefs.TitleField, value); }
|
set { SetEntryValue(PwDefs.TitleField, value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,6 +68,7 @@ namespace ModernKeePass.ViewModels
|
|||||||
NotifyPropertyChanged("PasswordComplexityIndicator");
|
NotifyPropertyChanged("PasswordComplexityIndicator");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Url
|
public string Url
|
||||||
{
|
{
|
||||||
get { return GetEntryValue(PwDefs.UrlField); }
|
get { return GetEntryValue(PwDefs.UrlField); }
|
||||||
@@ -117,6 +113,16 @@ namespace ModernKeePass.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsVisible
|
||||||
|
{
|
||||||
|
get { return _isVisible; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_isVisible = value;
|
||||||
|
NotifyPropertyChanged("IsVisible");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool IsRecycleOnDelete => _database.RecycleBinEnabled && !ParentGroup.IsSelected;
|
public bool IsRecycleOnDelete => _database.RecycleBinEnabled && !ParentGroup.IsSelected;
|
||||||
|
|
||||||
public bool IsRevealPassword
|
public bool IsRevealPassword
|
||||||
@@ -151,10 +157,11 @@ namespace ModernKeePass.ViewModels
|
|||||||
public event PropertyChangedEventHandler PropertyChanged;
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
|
||||||
private readonly PwEntry _pwEntry;
|
private readonly PwEntry _pwEntry;
|
||||||
private readonly IDatabase _database;
|
private readonly IDatabaseService _database;
|
||||||
private bool _isEditMode;
|
private bool _isEditMode;
|
||||||
private bool _isRevealPassword;
|
private bool _isRevealPassword;
|
||||||
private double _passwordLength = 25;
|
private double _passwordLength = 25;
|
||||||
|
private bool _isVisible = true;
|
||||||
|
|
||||||
private void NotifyPropertyChanged(string propertyName)
|
private void NotifyPropertyChanged(string propertyName)
|
||||||
{
|
{
|
||||||
@@ -163,9 +170,9 @@ namespace ModernKeePass.ViewModels
|
|||||||
|
|
||||||
public EntryVm() { }
|
public EntryVm() { }
|
||||||
|
|
||||||
internal EntryVm(PwEntry entry, GroupVm parent) : this(entry, parent, (Application.Current as App)?.Database) { }
|
internal EntryVm(PwEntry entry, GroupVm parent) : this(entry, parent, DatabaseService.Instance) { }
|
||||||
|
|
||||||
public EntryVm(PwEntry entry, GroupVm parent, IDatabase database)
|
public EntryVm(PwEntry entry, GroupVm parent, IDatabaseService database)
|
||||||
{
|
{
|
||||||
_database = database;
|
_database = database;
|
||||||
_pwEntry = entry;
|
_pwEntry = entry;
|
||||||
@@ -206,15 +213,16 @@ namespace ModernKeePass.ViewModels
|
|||||||
return _pwEntry?.Strings.GetSafe(key).ReadString();
|
return _pwEntry?.Strings.GetSafe(key).ReadString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[DatabaseChanged]
|
||||||
private void SetEntryValue(string key, string newValue)
|
private void SetEntryValue(string key, string newValue)
|
||||||
{
|
{
|
||||||
_pwEntry?.Strings.Set(key, new ProtectedString(true, newValue));
|
_pwEntry?.Strings.Set(key, new ProtectedString(true, newValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void MarkForDelete()
|
public void MarkForDelete(string recycleBinTitle)
|
||||||
{
|
{
|
||||||
if (_database.RecycleBinEnabled && _database.RecycleBin?.IdUuid == null)
|
if (_database.RecycleBinEnabled && _database.RecycleBin?.IdUuid == null)
|
||||||
_database.CreateRecycleBin();
|
_database.CreateRecycleBin(recycleBinTitle);
|
||||||
Move(_database.RecycleBinEnabled && !ParentGroup.IsSelected ? _database.RecycleBin : null);
|
Move(_database.RecycleBinEnabled && !ParentGroup.IsSelected ? _database.RecycleBin : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -3,11 +3,12 @@ using System.Collections.ObjectModel;
|
|||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Windows.UI.Xaml;
|
|
||||||
using Windows.UI.Xaml.Controls;
|
using Windows.UI.Xaml.Controls;
|
||||||
|
using ModernKeePass.Attributes;
|
||||||
using ModernKeePass.Common;
|
using ModernKeePass.Common;
|
||||||
using ModernKeePass.Interfaces;
|
using ModernKeePass.Interfaces;
|
||||||
using ModernKeePass.Mappings;
|
using ModernKeePass.Mappings;
|
||||||
|
using ModernKeePass.Services;
|
||||||
using ModernKeePassLib;
|
using ModernKeePassLib;
|
||||||
|
|
||||||
namespace ModernKeePass.ViewModels
|
namespace ModernKeePass.ViewModels
|
||||||
@@ -54,6 +55,7 @@ namespace ModernKeePass.ViewModels
|
|||||||
public string Name
|
public string Name
|
||||||
{
|
{
|
||||||
get { return _pwGroup == null ? string.Empty : _pwGroup.Name; }
|
get { return _pwGroup == null ? string.Empty : _pwGroup.Name; }
|
||||||
|
[DatabaseChanged]
|
||||||
set { _pwGroup.Name = value; }
|
set { _pwGroup.Name = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +63,6 @@ namespace ModernKeePass.ViewModels
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (_pwGroup == null) return Symbol.Add;
|
|
||||||
var result = PwIconToSegoeMapping.GetSymbolFromIcon(_pwGroup.IconId);
|
var result = PwIconToSegoeMapping.GetSymbolFromIcon(_pwGroup.IconId);
|
||||||
return result == Symbol.More ? Symbol.Folder : result;
|
return result == Symbol.More ? Symbol.Folder : result;
|
||||||
}
|
}
|
||||||
@@ -80,19 +81,6 @@ namespace ModernKeePass.ViewModels
|
|||||||
set { SetProperty(ref _isMenuClosed, value); }
|
set { SetProperty(ref _isMenuClosed, value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Filter
|
|
||||||
{
|
|
||||||
get { return _filter; }
|
|
||||||
set
|
|
||||||
{
|
|
||||||
SetProperty(ref _filter, value);
|
|
||||||
OnPropertyChanged("EntriesFiltered");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ObservableCollection<EntryVm> EntriesFiltered =>
|
|
||||||
new ObservableCollection<EntryVm>(Entries.Where(e => e.Name.IndexOf(Filter, StringComparison.OrdinalIgnoreCase) >= 0));
|
|
||||||
|
|
||||||
public string Path
|
public string Path
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -105,20 +93,19 @@ namespace ModernKeePass.ViewModels
|
|||||||
}
|
}
|
||||||
|
|
||||||
private readonly PwGroup _pwGroup;
|
private readonly PwGroup _pwGroup;
|
||||||
private readonly IDatabase _database;
|
private readonly IDatabaseService _database;
|
||||||
private bool _isEditMode;
|
private bool _isEditMode;
|
||||||
private PwEntry _reorderedEntry;
|
private PwEntry _reorderedEntry;
|
||||||
private ObservableCollection<EntryVm> _entries = new ObservableCollection<EntryVm>();
|
private ObservableCollection<EntryVm> _entries = new ObservableCollection<EntryVm>();
|
||||||
private string _filter = string.Empty;
|
|
||||||
private bool _isMenuClosed = true;
|
private bool _isMenuClosed = true;
|
||||||
|
|
||||||
public GroupVm() {}
|
public GroupVm() {}
|
||||||
|
|
||||||
internal GroupVm(PwGroup pwGroup, GroupVm parent, PwUuid recycleBinId = null) : this(pwGroup, parent,
|
internal GroupVm(PwGroup pwGroup, GroupVm parent, PwUuid recycleBinId = null) : this(pwGroup, parent,
|
||||||
(Application.Current as App)?.Database, recycleBinId)
|
DatabaseService.Instance, recycleBinId)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
public GroupVm(PwGroup pwGroup, GroupVm parent, IDatabase database, PwUuid recycleBinId = null)
|
public GroupVm(PwGroup pwGroup, GroupVm parent, IDatabaseService database, PwUuid recycleBinId = null)
|
||||||
{
|
{
|
||||||
_pwGroup = pwGroup;
|
_pwGroup = pwGroup;
|
||||||
_database = database;
|
_database = database;
|
||||||
@@ -128,9 +115,9 @@ namespace ModernKeePass.ViewModels
|
|||||||
Entries = new ObservableCollection<EntryVm>(pwGroup.Entries.Select(e => new EntryVm(e, this)));
|
Entries = new ObservableCollection<EntryVm>(pwGroup.Entries.Select(e => new EntryVm(e, this)));
|
||||||
Entries.CollectionChanged += Entries_CollectionChanged;
|
Entries.CollectionChanged += Entries_CollectionChanged;
|
||||||
Groups = new ObservableCollection<GroupVm>(pwGroup.Groups.Select(g => new GroupVm(g, this, recycleBinId)));
|
Groups = new ObservableCollection<GroupVm>(pwGroup.Groups.Select(g => new GroupVm(g, this, recycleBinId)));
|
||||||
Groups.Insert(0, new GroupVm());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[DatabaseChanged]
|
||||||
private void Entries_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
private void Entries_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||||
{
|
{
|
||||||
switch (e.Action)
|
switch (e.Action)
|
||||||
@@ -147,6 +134,7 @@ namespace ModernKeePass.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[DatabaseChanged]
|
||||||
public GroupVm AddNewGroup(string name = "")
|
public GroupVm AddNewGroup(string name = "")
|
||||||
{
|
{
|
||||||
var pwGroup = new PwGroup(true, true, name, PwIcon.Folder);
|
var pwGroup = new PwGroup(true, true, name, PwIcon.Folder);
|
||||||
@@ -165,10 +153,10 @@ namespace ModernKeePass.ViewModels
|
|||||||
return newEntry;
|
return newEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void MarkForDelete()
|
public void MarkForDelete(string recycleBinTitle)
|
||||||
{
|
{
|
||||||
if (_database.RecycleBinEnabled && _database.RecycleBin?.IdUuid == null)
|
if (_database.RecycleBinEnabled && _database.RecycleBin?.IdUuid == null)
|
||||||
_database.CreateRecycleBin();
|
_database.CreateRecycleBin(recycleBinTitle);
|
||||||
Move(_database.RecycleBinEnabled && !IsSelected ? _database.RecycleBin : null);
|
Move(_database.RecycleBinEnabled && !IsSelected ? _database.RecycleBin : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,6 +165,7 @@ namespace ModernKeePass.ViewModels
|
|||||||
Move(PreviousGroup);
|
Move(PreviousGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[DatabaseChanged]
|
||||||
public void Move(GroupVm destination)
|
public void Move(GroupVm destination)
|
||||||
{
|
{
|
||||||
PreviousGroup = ParentGroup;
|
PreviousGroup = ParentGroup;
|
||||||
@@ -204,6 +193,7 @@ namespace ModernKeePass.ViewModels
|
|||||||
_database.Save();
|
_database.Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[DatabaseChanged]
|
||||||
public void SortEntries()
|
public void SortEntries()
|
||||||
{
|
{
|
||||||
var comparer = new PwEntryComparer(PwDefs.TitleField, true, false);
|
var comparer = new PwEntryComparer(PwDefs.TitleField, true, false);
|
||||||
@@ -218,6 +208,7 @@ namespace ModernKeePass.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[DatabaseChanged]
|
||||||
public void SortGroups()
|
public void SortGroups()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
using Windows.Storage;
|
using Windows.Storage;
|
||||||
using ModernKeePass.Common;
|
using ModernKeePass.Common;
|
||||||
using Windows.UI.Xaml;
|
|
||||||
using ModernKeePass.Interfaces;
|
using ModernKeePass.Interfaces;
|
||||||
using ModernKeePass.Services;
|
using ModernKeePass.Services;
|
||||||
|
|
||||||
@@ -31,20 +30,20 @@ namespace ModernKeePass.ViewModels
|
|||||||
|
|
||||||
public void OpenDatabaseFile()
|
public void OpenDatabaseFile()
|
||||||
{
|
{
|
||||||
OpenDatabaseFile((Application.Current as App)?.Database);
|
OpenDatabaseFile(DatabaseService.Instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OpenDatabaseFile(IDatabase database)
|
public void OpenDatabaseFile(IDatabaseService database)
|
||||||
{
|
{
|
||||||
database.DatabaseFile = DatabaseFile;
|
database.DatabaseFile = DatabaseFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateAccessTime()
|
public void UpdateAccessTime()
|
||||||
{
|
{
|
||||||
UpdateAccessTime(new RecentService());
|
UpdateAccessTime(RecentService.Instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void UpdateAccessTime(IRecent recent)
|
public async void UpdateAccessTime(IRecentService recent)
|
||||||
{
|
{
|
||||||
await recent.GetFileAsync(Token);
|
await recent.GetFileAsync(Token);
|
||||||
}
|
}
|
||||||
|
@@ -2,9 +2,9 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Windows.UI.Xaml;
|
|
||||||
using ModernKeePass.Common;
|
using ModernKeePass.Common;
|
||||||
using ModernKeePass.Interfaces;
|
using ModernKeePass.Interfaces;
|
||||||
|
using ModernKeePass.Services;
|
||||||
using ModernKeePassLib;
|
using ModernKeePassLib;
|
||||||
using ModernKeePassLib.Cryptography.Cipher;
|
using ModernKeePassLib.Cryptography.Cipher;
|
||||||
using ModernKeePassLib.Cryptography.KeyDerivation;
|
using ModernKeePassLib.Cryptography.KeyDerivation;
|
||||||
@@ -14,7 +14,7 @@ namespace ModernKeePass.ViewModels
|
|||||||
// TODO: implement Kdf settings
|
// TODO: implement Kdf settings
|
||||||
public class SettingsDatabaseVm: NotifyPropertyChangedBase, IHasSelectableObject
|
public class SettingsDatabaseVm: NotifyPropertyChangedBase, IHasSelectableObject
|
||||||
{
|
{
|
||||||
private readonly IDatabase _database;
|
private readonly IDatabaseService _database;
|
||||||
private GroupVm _selectedItem;
|
private GroupVm _selectedItem;
|
||||||
|
|
||||||
public bool HasRecycleBin
|
public bool HasRecycleBin
|
||||||
@@ -27,6 +27,15 @@ namespace ModernKeePass.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsNewRecycleBin
|
||||||
|
{
|
||||||
|
get { return _database.RecycleBin == null; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value) _database.RecycleBin = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public ObservableCollection<GroupVm> Groups { get; set; }
|
public ObservableCollection<GroupVm> Groups { get; set; }
|
||||||
|
|
||||||
public IEnumerable<string> Ciphers
|
public IEnumerable<string> Ciphers
|
||||||
@@ -73,7 +82,7 @@ namespace ModernKeePass.ViewModels
|
|||||||
get { return Groups.FirstOrDefault(g => g.IsSelected); }
|
get { return Groups.FirstOrDefault(g => g.IsSelected); }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (_selectedItem == value) return;
|
if (_selectedItem == value || IsNewRecycleBin) return;
|
||||||
if (_selectedItem != null)
|
if (_selectedItem != null)
|
||||||
{
|
{
|
||||||
_selectedItem.IsSelected = false;
|
_selectedItem.IsSelected = false;
|
||||||
@@ -88,9 +97,9 @@ namespace ModernKeePass.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public SettingsDatabaseVm() : this((Application.Current as App)?.Database) { }
|
public SettingsDatabaseVm() : this(DatabaseService.Instance) { }
|
||||||
|
|
||||||
public SettingsDatabaseVm(IDatabase database)
|
public SettingsDatabaseVm(IDatabaseService database)
|
||||||
{
|
{
|
||||||
_database = database;
|
_database = database;
|
||||||
Groups = _database?.RootGroup.Groups;
|
Groups = _database?.RootGroup.Groups;
|
||||||
|
@@ -6,12 +6,12 @@ namespace ModernKeePass.ViewModels
|
|||||||
{
|
{
|
||||||
public class SettingsNewVm
|
public class SettingsNewVm
|
||||||
{
|
{
|
||||||
private ISettings _settings;
|
private readonly ISettingsService _settings;
|
||||||
|
|
||||||
public SettingsNewVm() : this(new SettingsService())
|
public SettingsNewVm() : this(SettingsService.Instance)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
public SettingsNewVm(ISettings settings)
|
public SettingsNewVm(ISettingsService settings)
|
||||||
{
|
{
|
||||||
_settings = settings;
|
_settings = settings;
|
||||||
}
|
}
|
||||||
|
24
ModernKeePass/ViewModels/Items/SettingsSaveVm.cs
Normal file
24
ModernKeePass/ViewModels/Items/SettingsSaveVm.cs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
using ModernKeePass.Interfaces;
|
||||||
|
using ModernKeePass.Services;
|
||||||
|
|
||||||
|
namespace ModernKeePass.ViewModels
|
||||||
|
{
|
||||||
|
public class SettingsSaveVm
|
||||||
|
{
|
||||||
|
private readonly ISettingsService _settings;
|
||||||
|
|
||||||
|
public SettingsSaveVm() : this(SettingsService.Instance)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
public SettingsSaveVm(ISettingsService settings)
|
||||||
|
{
|
||||||
|
_settings = settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsSaveSuspend
|
||||||
|
{
|
||||||
|
get { return _settings.GetSetting("SaveSuspend", true); }
|
||||||
|
set { _settings.PutSetting("SaveSuspend", value); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,7 +1,6 @@
|
|||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Windows.ApplicationModel;
|
using Windows.ApplicationModel;
|
||||||
using Windows.UI.Xaml;
|
|
||||||
using Windows.UI.Xaml.Controls;
|
using Windows.UI.Xaml.Controls;
|
||||||
using ModernKeePass.Common;
|
using ModernKeePass.Common;
|
||||||
using ModernKeePass.Interfaces;
|
using ModernKeePass.Interfaces;
|
||||||
@@ -46,12 +45,12 @@ namespace ModernKeePass.ViewModels
|
|||||||
public MainVm() {}
|
public MainVm() {}
|
||||||
|
|
||||||
internal MainVm(Frame referenceFrame, Frame destinationFrame) : this(referenceFrame, destinationFrame,
|
internal MainVm(Frame referenceFrame, Frame destinationFrame) : this(referenceFrame, destinationFrame,
|
||||||
(Application.Current as App)?.Database, new ResourcesService(), new RecentService())
|
DatabaseService.Instance, new ResourcesService(), RecentService.Instance)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
public MainVm(Frame referenceFrame, Frame destinationFrame, IDatabase database, IResource resource, IRecent recent)
|
public MainVm(Frame referenceFrame, Frame destinationFrame, IDatabaseService database, IResourceService resource, IRecentService recent)
|
||||||
{
|
{
|
||||||
var isDatabaseOpen = database != null && database.Status == (int) DatabaseService.DatabaseStatus.Opened;
|
var isDatabaseOpen = database != null && database.IsOpen;
|
||||||
|
|
||||||
var mainMenuItems = new ObservableCollection<MainMenuItemVm>
|
var mainMenuItems = new ObservableCollection<MainMenuItemVm>
|
||||||
{
|
{
|
||||||
@@ -62,7 +61,7 @@ namespace ModernKeePass.ViewModels
|
|||||||
Destination = destinationFrame,
|
Destination = destinationFrame,
|
||||||
Parameter = referenceFrame,
|
Parameter = referenceFrame,
|
||||||
SymbolIcon = Symbol.Page2,
|
SymbolIcon = Symbol.Page2,
|
||||||
IsSelected = database != null && database.Status == (int) DatabaseService.DatabaseStatus.Opening
|
IsSelected = database != null && database.IsFileOpen && !database.IsOpen
|
||||||
},
|
},
|
||||||
new MainMenuItemVm
|
new MainMenuItemVm
|
||||||
{
|
{
|
||||||
@@ -90,7 +89,7 @@ namespace ModernKeePass.ViewModels
|
|||||||
Parameter = referenceFrame,
|
Parameter = referenceFrame,
|
||||||
SymbolIcon = Symbol.Copy,
|
SymbolIcon = Symbol.Copy,
|
||||||
IsSelected =
|
IsSelected =
|
||||||
(database == null || database.Status == (int) DatabaseService.DatabaseStatus.Closed) &&
|
(database == null || database.IsClosed) &&
|
||||||
recent.EntryCount > 0,
|
recent.EntryCount > 0,
|
||||||
IsEnabled = recent.EntryCount > 0
|
IsEnabled = recent.EntryCount > 0
|
||||||
},
|
},
|
||||||
@@ -120,7 +119,7 @@ namespace ModernKeePass.ViewModels
|
|||||||
SelectedItem = mainMenuItems.FirstOrDefault(m => m.IsSelected);
|
SelectedItem = mainMenuItems.FirstOrDefault(m => m.IsSelected);
|
||||||
|
|
||||||
// Add currently opened database to the menu
|
// Add currently opened database to the menu
|
||||||
if (database != null && database.Status == (int) DatabaseService.DatabaseStatus.Opened)
|
if (database != null && database.IsOpen)
|
||||||
mainMenuItems.Add(new MainMenuItemVm
|
mainMenuItems.Add(new MainMenuItemVm
|
||||||
{
|
{
|
||||||
Title = database.Name,
|
Title = database.Name,
|
||||||
|
@@ -1,5 +1,4 @@
|
|||||||
using Windows.Storage;
|
using Windows.Storage;
|
||||||
using Windows.UI.Xaml;
|
|
||||||
using ModernKeePass.Common;
|
using ModernKeePass.Common;
|
||||||
using ModernKeePass.Interfaces;
|
using ModernKeePass.Interfaces;
|
||||||
using ModernKeePass.Services;
|
using ModernKeePass.Services;
|
||||||
@@ -8,27 +7,27 @@ namespace ModernKeePass.ViewModels
|
|||||||
{
|
{
|
||||||
public class OpenVm: NotifyPropertyChangedBase
|
public class OpenVm: NotifyPropertyChangedBase
|
||||||
{
|
{
|
||||||
public bool ShowPasswordBox => _database?.Status == (int) DatabaseService.DatabaseStatus.Opening;
|
public bool ShowPasswordBox => _database.IsFileOpen;
|
||||||
|
|
||||||
public string Name => _database?.Name;
|
public string Name => _database?.Name;
|
||||||
|
|
||||||
private readonly IDatabase _database;
|
private readonly IDatabaseService _database;
|
||||||
|
|
||||||
public OpenVm() : this((Application.Current as App)?.Database) { }
|
public OpenVm() : this(DatabaseService.Instance) { }
|
||||||
|
|
||||||
public OpenVm(IDatabase database)
|
public OpenVm(IDatabaseService database)
|
||||||
{
|
{
|
||||||
_database = database;
|
_database = database;
|
||||||
if (database == null || database.Status != (int) DatabaseService.DatabaseStatus.Opening) return;
|
if (database == null || !database.IsFileOpen) return;
|
||||||
OpenFile(database.DatabaseFile);
|
OpenFile(database.DatabaseFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OpenFile(StorageFile file)
|
public void OpenFile(StorageFile file)
|
||||||
{
|
{
|
||||||
OpenFile(file, new RecentService());
|
OpenFile(file, RecentService.Instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OpenFile(StorageFile file, IRecent recent)
|
public void OpenFile(StorageFile file, IRecentService recent)
|
||||||
{
|
{
|
||||||
_database.DatabaseFile = file;
|
_database.DatabaseFile = file;
|
||||||
OnPropertyChanged("Name");
|
OnPropertyChanged("Name");
|
||||||
@@ -36,7 +35,7 @@ namespace ModernKeePass.ViewModels
|
|||||||
AddToRecentList(file, recent);
|
AddToRecentList(file, recent);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddToRecentList(StorageFile file, IRecent recent)
|
private void AddToRecentList(StorageFile file, IRecentService recent)
|
||||||
{
|
{
|
||||||
recent.Add(file, file.DisplayName);
|
recent.Add(file, file.DisplayName);
|
||||||
}
|
}
|
||||||
|
@@ -7,7 +7,7 @@ namespace ModernKeePass.ViewModels
|
|||||||
{
|
{
|
||||||
public class RecentVm : NotifyPropertyChangedBase, IHasSelectableObject
|
public class RecentVm : NotifyPropertyChangedBase, IHasSelectableObject
|
||||||
{
|
{
|
||||||
private readonly IRecent _recent;
|
private readonly IRecentService _recent;
|
||||||
private ISelectableModel _selectedItem;
|
private ISelectableModel _selectedItem;
|
||||||
private ObservableCollection<IRecentItem> _recentItems = new ObservableCollection<IRecentItem>();
|
private ObservableCollection<IRecentItem> _recentItems = new ObservableCollection<IRecentItem>();
|
||||||
|
|
||||||
@@ -35,10 +35,10 @@ namespace ModernKeePass.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public RecentVm() : this (new RecentService())
|
public RecentVm() : this (RecentService.Instance)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
public RecentVm(IRecent recent)
|
public RecentVm(IRecentService recent)
|
||||||
{
|
{
|
||||||
_recent = recent;
|
_recent = recent;
|
||||||
RecentItems = _recent.GetAllFiles();
|
RecentItems = _recent.GetAllFiles();
|
||||||
|
@@ -1,23 +1,25 @@
|
|||||||
using Windows.Storage;
|
using System.Threading.Tasks;
|
||||||
using Windows.UI.Xaml;
|
using Windows.Storage;
|
||||||
using ModernKeePass.Interfaces;
|
using ModernKeePass.Interfaces;
|
||||||
|
using ModernKeePass.Services;
|
||||||
|
|
||||||
namespace ModernKeePass.ViewModels
|
namespace ModernKeePass.ViewModels
|
||||||
{
|
{
|
||||||
public class SaveVm
|
public class SaveVm
|
||||||
{
|
{
|
||||||
private readonly IDatabase _database;
|
private readonly IDatabaseService _database;
|
||||||
public SaveVm() : this((Application.Current as App)?.Database) { }
|
public SaveVm() : this(DatabaseService.Instance) { }
|
||||||
|
|
||||||
public SaveVm(IDatabase database)
|
public SaveVm(IDatabaseService database)
|
||||||
{
|
{
|
||||||
_database = database;
|
_database = database;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Save(bool close = true)
|
public async Task Save(bool close = true)
|
||||||
{
|
{
|
||||||
_database.Save();
|
_database.Save();
|
||||||
if (close) _database.Close();
|
if (close)
|
||||||
|
await _database.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Save(StorageFile file)
|
public void Save(StorageFile file)
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Windows.UI.Xaml;
|
|
||||||
using Windows.UI.Xaml.Controls;
|
using Windows.UI.Xaml.Controls;
|
||||||
using ModernKeePass.Common;
|
using ModernKeePass.Common;
|
||||||
using ModernKeePass.Interfaces;
|
using ModernKeePass.Interfaces;
|
||||||
@@ -41,9 +40,9 @@ namespace ModernKeePass.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public SettingsVm() : this((Application.Current as App)?.Database, new ResourcesService()) { }
|
public SettingsVm() : this(DatabaseService.Instance, new ResourcesService()) { }
|
||||||
|
|
||||||
public SettingsVm(IDatabase database, IResource resource)
|
public SettingsVm(IDatabaseService database, IResourceService resource)
|
||||||
{
|
{
|
||||||
var menuItems = new ObservableCollection<ListMenuItemVm>
|
var menuItems = new ObservableCollection<ListMenuItemVm>
|
||||||
{
|
{
|
||||||
@@ -56,12 +55,19 @@ namespace ModernKeePass.ViewModels
|
|||||||
IsSelected = true
|
IsSelected = true
|
||||||
},
|
},
|
||||||
new ListMenuItemVm
|
new ListMenuItemVm
|
||||||
|
{
|
||||||
|
Title = resource.GetResourceValue("SettingsMenuItemSave"),
|
||||||
|
Group = resource.GetResourceValue("SettingsMenuGroupApplication"),
|
||||||
|
SymbolIcon = Symbol.Save,
|
||||||
|
PageType = typeof(SettingsSavePage)
|
||||||
|
},
|
||||||
|
new ListMenuItemVm
|
||||||
{
|
{
|
||||||
Title = resource.GetResourceValue("SettingsMenuItemGeneral"),
|
Title = resource.GetResourceValue("SettingsMenuItemGeneral"),
|
||||||
Group = resource.GetResourceValue("SettingsMenuGroupDatabase"),
|
Group = resource.GetResourceValue("SettingsMenuGroupDatabase"),
|
||||||
SymbolIcon = Symbol.Setting,
|
SymbolIcon = Symbol.Setting,
|
||||||
PageType = typeof(SettingsDatabasePage),
|
PageType = typeof(SettingsDatabasePage),
|
||||||
IsEnabled = database?.Status == 2
|
IsEnabled = database.IsOpen
|
||||||
},
|
},
|
||||||
new ListMenuItemVm
|
new ListMenuItemVm
|
||||||
{
|
{
|
||||||
@@ -69,7 +75,7 @@ namespace ModernKeePass.ViewModels
|
|||||||
Group = resource.GetResourceValue("SettingsMenuGroupDatabase"),
|
Group = resource.GetResourceValue("SettingsMenuGroupDatabase"),
|
||||||
SymbolIcon = Symbol.Permissions,
|
SymbolIcon = Symbol.Permissions,
|
||||||
PageType = typeof(SettingsSecurityPage),
|
PageType = typeof(SettingsSecurityPage),
|
||||||
IsEnabled = database?.Status == 2
|
IsEnabled = database.IsOpen
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
SelectedItem = menuItems.FirstOrDefault(m => m.IsSelected);
|
SelectedItem = menuItems.FirstOrDefault(m => m.IsSelected);
|
||||||
|
@@ -458,7 +458,13 @@
|
|||||||
<ProgressBar Value="{Binding PasswordComplexityIndicator, ConverterParameter=0\,128, Converter={StaticResource ProgressBarLegalValuesConverter}}" Maximum="128" Width="350" HorizontalAlignment="Left" Foreground="{Binding PasswordComplexityIndicator, ConverterParameter=128, Converter={StaticResource DoubleToForegroungBrushComplexityConverter}}" />
|
<ProgressBar Value="{Binding PasswordComplexityIndicator, ConverterParameter=0\,128, Converter={StaticResource ProgressBarLegalValuesConverter}}" Maximum="128" Width="350" HorizontalAlignment="Left" Foreground="{Binding PasswordComplexityIndicator, ConverterParameter=128, Converter={StaticResource DoubleToForegroungBrushComplexityConverter}}" />
|
||||||
<CheckBox x:Uid="EntryShowPassword" HorizontalAlignment="Left" Margin="-3,0,0,0" IsChecked="{Binding IsRevealPassword, Mode=TwoWay}" IsEnabled="{Binding IsRevealPasswordEnabled}" />
|
<CheckBox x:Uid="EntryShowPassword" HorizontalAlignment="Left" Margin="-3,0,0,0" IsChecked="{Binding IsRevealPassword, Mode=TwoWay}" IsEnabled="{Binding IsRevealPasswordEnabled}" />
|
||||||
<TextBlock TextWrapping="Wrap" Text="URL" FontSize="18"/>
|
<TextBlock TextWrapping="Wrap" Text="URL" FontSize="18"/>
|
||||||
<local:TextBoxWithButton x:Name="UrlTextBox" HorizontalAlignment="Left" Text="{Binding Url, Mode=TwoWay}" Height="32" Width="350" MaxLength="256" Style="{StaticResource TextBoxWithButtonStyle}" ButtonClick="UrlButton_Click" ButtonSymbol="" ButtonTooltip="Navigate to URL" />
|
<local:TextBoxWithButton x:Name="UrlTextBox" HorizontalAlignment="Left" Text="{Binding Url, Mode=TwoWay}" Height="32" Width="350" MaxLength="256" Style="{StaticResource TextBoxWithButtonStyle}" ButtonSymbol="" ButtonTooltip="Navigate to URL">
|
||||||
|
<interactivity:Interaction.Behaviors>
|
||||||
|
<core:EventTriggerBehavior EventName="ButtonClick">
|
||||||
|
<actions:NavigateToUrlAction Url="{Binding Url}" />
|
||||||
|
</core:EventTriggerBehavior>
|
||||||
|
</interactivity:Interaction.Behaviors>
|
||||||
|
</local:TextBoxWithButton>
|
||||||
<TextBlock x:Uid="EntryNotes" TextWrapping="Wrap" FontSize="18" />
|
<TextBlock x:Uid="EntryNotes" TextWrapping="Wrap" FontSize="18" />
|
||||||
<TextBox HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding Notes, Mode=TwoWay}" Width="350" Height="200" AcceptsReturn="True" IsSpellCheckEnabled="True" />
|
<TextBox HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding Notes, Mode=TwoWay}" Width="350" Height="200" AcceptsReturn="True" IsSpellCheckEnabled="True" />
|
||||||
<CheckBox x:Uid="EntryExpirationDate" FontSize="18" IsChecked="{Binding HasExpirationDate, Mode=TwoWay}" />
|
<CheckBox x:Uid="EntryExpirationDate" FontSize="18" IsChecked="{Binding HasExpirationDate, Mode=TwoWay}" />
|
||||||
|
@@ -81,9 +81,9 @@ namespace ModernKeePass.Views
|
|||||||
resource.GetResourceValue("EntityDeleteCancelButton"), a =>
|
resource.GetResourceValue("EntityDeleteCancelButton"), a =>
|
||||||
{
|
{
|
||||||
ToastNotificationHelper.ShowMovedToast(Model, resource.GetResourceValue("EntityDeleting"), text);
|
ToastNotificationHelper.ShowMovedToast(Model, resource.GetResourceValue("EntityDeleting"), text);
|
||||||
Model.MarkForDelete();
|
Model.MarkForDelete(resource.GetResourceValue("RecycleBinTitle"));
|
||||||
if (Frame.CanGoBack) Frame.GoBack();
|
if (Frame.CanGoBack) Frame.GoBack();
|
||||||
});
|
}, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RestoreButton_Click(object sender, RoutedEventArgs e)
|
private void RestoreButton_Click(object sender, RoutedEventArgs e)
|
||||||
@@ -93,19 +93,6 @@ namespace ModernKeePass.Views
|
|||||||
if (Frame.CanGoBack) Frame.GoBack();
|
if (Frame.CanGoBack) Frame.GoBack();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void UrlButton_Click(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var uri = new Uri(UrlTextBox.Text);
|
|
||||||
await Windows.System.Launcher.LaunchUriAsync(uri);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
MessageDialogHelper.ShowErrorDialog(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void EntryDetailPage_OnSizeChanged(object sender, SizeChangedEventArgs e)
|
private void EntryDetailPage_OnSizeChanged(object sender, SizeChangedEventArgs e)
|
||||||
{
|
{
|
||||||
VisualStateManager.GoToState(this, e.NewSize.Width < 700 ? "Small" : "Large", true);
|
VisualStateManager.GoToState(this, e.NewSize.Width < 700 ? "Small" : "Large", true);
|
||||||
|
@@ -8,7 +8,6 @@
|
|||||||
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
|
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
|
||||||
xmlns:core="using:Microsoft.Xaml.Interactions.Core"
|
xmlns:core="using:Microsoft.Xaml.Interactions.Core"
|
||||||
xmlns:actions="using:ModernKeePass.Actions"
|
xmlns:actions="using:ModernKeePass.Actions"
|
||||||
xmlns:controls="using:ModernKeePass.Controls"
|
|
||||||
xmlns:templateSelectors="using:ModernKeePass.TemplateSelectors"
|
xmlns:templateSelectors="using:ModernKeePass.TemplateSelectors"
|
||||||
x:Name="PageRoot"
|
x:Name="PageRoot"
|
||||||
x:Class="ModernKeePass.Views.GroupDetailPage"
|
x:Class="ModernKeePass.Views.GroupDetailPage"
|
||||||
@@ -16,7 +15,6 @@
|
|||||||
SizeChanged="GroupDetailPage_OnSizeChanged">
|
SizeChanged="GroupDetailPage_OnSizeChanged">
|
||||||
<Page.Resources>
|
<Page.Resources>
|
||||||
<converters:ColorToBrushConverter x:Key="ColorToBrushConverter"/>
|
<converters:ColorToBrushConverter x:Key="ColorToBrushConverter"/>
|
||||||
<converters:BooleanToFontStyleConverter x:Key="BooleanToFontStyleConverter"/>
|
|
||||||
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
|
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
|
||||||
<converters:InverseBooleanToVisibilityConverter x:Key="InverseBooleanToVisibilityConverter"/>
|
<converters:InverseBooleanToVisibilityConverter x:Key="InverseBooleanToVisibilityConverter"/>
|
||||||
<converters:NullToBooleanConverter x:Key="NullToBooleanConverter"/>
|
<converters:NullToBooleanConverter x:Key="NullToBooleanConverter"/>
|
||||||
@@ -84,7 +82,7 @@
|
|||||||
</core:EventTriggerBehavior>
|
</core:EventTriggerBehavior>
|
||||||
</interactivity:Interaction.Behaviors>
|
</interactivity:Interaction.Behaviors>
|
||||||
</AppBarButton>
|
</AppBarButton>
|
||||||
<AppBarButton Icon="Delete" x:Uid="AppBarDelete" IsEnabled="{Binding IsNotRoot}" Click="DeleteButton_Click" />
|
<AppBarButton Icon="Delete" x:Uid="AppBarDelete" IsEnabled="{Binding IsNotRoot}" Visibility="{Binding IsSelected, Converter={StaticResource InverseBooleanToVisibilityConverter}}" Click="DeleteButton_Click" />
|
||||||
</CommandBar>
|
</CommandBar>
|
||||||
</Page.BottomAppBar>
|
</Page.BottomAppBar>
|
||||||
<Grid>
|
<Grid>
|
||||||
@@ -94,7 +92,7 @@
|
|||||||
Source="{Binding Groups}" />
|
Source="{Binding Groups}" />
|
||||||
<CollectionViewSource
|
<CollectionViewSource
|
||||||
x:Name="EntriesViewSource"
|
x:Name="EntriesViewSource"
|
||||||
Source="{Binding EntriesFiltered}" />
|
Source="{Binding Entries}" />
|
||||||
<CollectionViewSource
|
<CollectionViewSource
|
||||||
x:Name="EntriesZoomedOutViewSource"
|
x:Name="EntriesZoomedOutViewSource"
|
||||||
Source="{Binding EntriesZoomedOut}" IsSourceGrouped="True"/>
|
Source="{Binding EntriesZoomedOut}" IsSourceGrouped="True"/>
|
||||||
@@ -127,27 +125,30 @@
|
|||||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
|
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
|
||||||
Foreground="{ThemeResource DefaultTextForegroundThemeBrush}">
|
Foreground="{ThemeResource DefaultTextForegroundThemeBrush}">
|
||||||
<ListView.Resources>
|
<ListView.Resources>
|
||||||
<DataTemplate x:Name="GroupOtherItem">
|
<DataTemplate x:Name="IsRecycleBin">
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<SymbolIcon Symbol="{Binding IconSymbol}" Margin="8,0,0,0">
|
<SymbolIcon Symbol="{Binding IconSymbol}" Margin="8,0,0,0">
|
||||||
<ToolTipService.ToolTip>
|
<ToolTipService.ToolTip>
|
||||||
<ToolTip Content="{Binding Name}" />
|
<ToolTip Content="{Binding Name}" />
|
||||||
</ToolTipService.ToolTip>
|
</ToolTipService.ToolTip>
|
||||||
</SymbolIcon>
|
</SymbolIcon>
|
||||||
<TextBlock Text="{Binding Name}" x:Name="GroupTextBlock" TextWrapping="NoWrap" VerticalAlignment="Center" Margin="30,0,20,0" FontStyle="{Binding IsSelected, Converter={StaticResource BooleanToFontStyleConverter}}" />
|
<TextBlock Text="{Binding Name}" x:Name="GroupTextBlock" TextWrapping="NoWrap" VerticalAlignment="Center" Margin="30,0,20,0" FontStyle="Italic" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
<DataTemplate x:Name="GroupFirstItem">
|
<DataTemplate x:Name="IsNotRecycleBin">
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<SymbolIcon Symbol="{Binding IconSymbol}" Margin="8,0,0,0">
|
<SymbolIcon Symbol="{Binding IconSymbol}" Margin="8,0,0,0">
|
||||||
<ToolTipService.ToolTip>
|
<ToolTipService.ToolTip>
|
||||||
<ToolTip x:Uid="GroupNewItemTooltip" />
|
<ToolTip Content="{Binding Name}" />
|
||||||
</ToolTipService.ToolTip>
|
</ToolTipService.ToolTip>
|
||||||
</SymbolIcon>
|
</SymbolIcon>
|
||||||
<TextBlock x:Name="GroupTextBlock" x:Uid="GroupNewItemTextBox" FontWeight="SemiBold" TextWrapping="NoWrap" VerticalAlignment="Center" Margin="30,0,20,0" />
|
<TextBlock Text="{Binding Name}" x:Name="GroupTextBlock" TextWrapping="NoWrap" VerticalAlignment="Center" Margin="30,0,20,0" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ListView.Resources>
|
</ListView.Resources>
|
||||||
|
<ListView.ItemTemplateSelector>
|
||||||
|
<templateSelectors:SelectableDataTemplateSelector FalseItem="{StaticResource IsNotRecycleBin}" TrueItem="{StaticResource IsRecycleBin}" />
|
||||||
|
</ListView.ItemTemplateSelector>
|
||||||
<ListView.ItemsSource>
|
<ListView.ItemsSource>
|
||||||
<Binding Source="{StaticResource GroupsViewSource}"/>
|
<Binding Source="{StaticResource GroupsViewSource}"/>
|
||||||
</ListView.ItemsSource>
|
</ListView.ItemsSource>
|
||||||
@@ -173,13 +174,25 @@
|
|||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ListView.HeaderTemplate>
|
</ListView.HeaderTemplate>
|
||||||
<ListView.ItemTemplateSelector>
|
<ListView.FooterTemplate>
|
||||||
<templateSelectors:FirstItemDataTemplateSelector
|
<DataTemplate>
|
||||||
FirstItem="{StaticResource GroupFirstItem}"
|
<StackPanel Orientation="Vertical" Visibility="{Binding IsSelected, Converter={StaticResource InverseBooleanToVisibilityConverter}}">
|
||||||
OtherItem="{StaticResource GroupOtherItem}" />
|
<Border BorderBrush="White" BorderThickness="0,0,0,1" />
|
||||||
</ListView.ItemTemplateSelector>
|
<Button Padding="0" Height="50" Margin="0" Style="{StaticResource NoBorderButtonStyle}" Background="Transparent" BorderThickness="0" Click="CreateGroup_ButtonClick">
|
||||||
|
<StackPanel Orientation="Horizontal" Margin="13,0,5,0">
|
||||||
|
<SymbolIcon Symbol="Add">
|
||||||
|
<ToolTipService.ToolTip>
|
||||||
|
<ToolTip x:Uid="GroupNewItemTooltip" />
|
||||||
|
</ToolTipService.ToolTip>
|
||||||
|
</SymbolIcon>
|
||||||
|
<TextBlock x:Uid="GroupNewItemTextBox" FontWeight="SemiBold" TextWrapping="NoWrap" FontSize="16" VerticalAlignment="Center" Margin="30,0,20,0" />
|
||||||
|
</StackPanel>
|
||||||
|
</Button>
|
||||||
|
</StackPanel>
|
||||||
|
</DataTemplate>
|
||||||
|
</ListView.FooterTemplate>
|
||||||
</ListView>
|
</ListView>
|
||||||
<!-- Horizontal scrolling grid -->
|
<TextBlock Grid.Column="1" x:Uid="ReorderEntriesLabel" Margin="20,20,0,0" Visibility="{Binding IsEditMode, Converter={StaticResource BooleanToVisibilityConverter}}" Style="{StaticResource BodyTextBlockStyle}" />
|
||||||
<HyperlinkButton Grid.Column="1" VerticalAlignment="Top" Margin="40,10,0,0" Click="CreateEntry_ButtonClick" Visibility="{Binding IsSelected, Converter={StaticResource InverseBooleanToVisibilityConverter}}" HorizontalAlignment="Right">
|
<HyperlinkButton Grid.Column="1" VerticalAlignment="Top" Margin="40,10,0,0" Click="CreateEntry_ButtonClick" Visibility="{Binding IsSelected, Converter={StaticResource InverseBooleanToVisibilityConverter}}" HorizontalAlignment="Right">
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<SymbolIcon Symbol="Add"></SymbolIcon>
|
<SymbolIcon Symbol="Add"></SymbolIcon>
|
||||||
@@ -188,6 +201,7 @@
|
|||||||
</HyperlinkButton>
|
</HyperlinkButton>
|
||||||
<SemanticZoom Grid.Column="1" ViewChangeStarted="SemanticZoom_ViewChangeStarted" Margin="20,60,0,0">
|
<SemanticZoom Grid.Column="1" ViewChangeStarted="SemanticZoom_ViewChangeStarted" Margin="20,60,0,0">
|
||||||
<SemanticZoom.ZoomedInView>
|
<SemanticZoom.ZoomedInView>
|
||||||
|
<!-- Horizontal scrolling grid -->
|
||||||
<GridView
|
<GridView
|
||||||
x:Name="GridView"
|
x:Name="GridView"
|
||||||
AutomationProperties.AutomationId="ItemGridView"
|
AutomationProperties.AutomationId="ItemGridView"
|
||||||
@@ -211,6 +225,7 @@
|
|||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="Auto"/>
|
<ColumnDefinition Width="Auto"/>
|
||||||
<ColumnDefinition Width="*"/>
|
<ColumnDefinition Width="*"/>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<SymbolIcon Grid.Column="0" Symbol="{Binding IconSymbol}" Width="100" Height="100" RenderTransformOrigin="0.5,0.5" >
|
<SymbolIcon Grid.Column="0" Symbol="{Binding IconSymbol}" Width="100" Height="100" RenderTransformOrigin="0.5,0.5" >
|
||||||
<SymbolIcon.RenderTransform>
|
<SymbolIcon.RenderTransform>
|
||||||
@@ -223,6 +238,34 @@
|
|||||||
<TextBlock Text="{Binding UserName}" Style="{StaticResource BodyTextBlockStyle}" MaxHeight="60" />
|
<TextBlock Text="{Binding UserName}" Style="{StaticResource BodyTextBlockStyle}" MaxHeight="60" />
|
||||||
<TextBlock Text="{Binding Url}" Style="{StaticResource BodyTextBlockStyle}" MaxHeight="60" />
|
<TextBlock Text="{Binding Url}" Style="{StaticResource BodyTextBlockStyle}" MaxHeight="60" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
<Button Grid.Column="2" Style="{StaticResource NoBorderButtonStyle}" VerticalAlignment="Bottom">
|
||||||
|
<SymbolIcon Symbol="More" />
|
||||||
|
<Button.Flyout>
|
||||||
|
<MenuFlyout>
|
||||||
|
<MenuFlyoutItem x:Uid="EntryItemCopyLogin">
|
||||||
|
<interactivity:Interaction.Behaviors>
|
||||||
|
<core:EventTriggerBehavior EventName="Click">
|
||||||
|
<actions:ClipboardAction Text="{Binding UserName}" />
|
||||||
|
</core:EventTriggerBehavior>
|
||||||
|
</interactivity:Interaction.Behaviors>
|
||||||
|
</MenuFlyoutItem>
|
||||||
|
<MenuFlyoutItem x:Uid="EntryItemCopyPassword">
|
||||||
|
<interactivity:Interaction.Behaviors>
|
||||||
|
<core:EventTriggerBehavior EventName="Click">
|
||||||
|
<actions:ClipboardAction Text="{Binding Password}" />
|
||||||
|
</core:EventTriggerBehavior>
|
||||||
|
</interactivity:Interaction.Behaviors>
|
||||||
|
</MenuFlyoutItem>
|
||||||
|
<MenuFlyoutItem x:Uid="EntryItemCopyUrl">
|
||||||
|
<interactivity:Interaction.Behaviors>
|
||||||
|
<core:EventTriggerBehavior EventName="Click">
|
||||||
|
<actions:NavigateToUrlAction Url="{Binding Url}" />
|
||||||
|
</core:EventTriggerBehavior>
|
||||||
|
</interactivity:Interaction.Behaviors>
|
||||||
|
</MenuFlyoutItem>
|
||||||
|
</MenuFlyout>
|
||||||
|
</Button.Flyout>
|
||||||
|
</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</GridView.ItemTemplate>
|
</GridView.ItemTemplate>
|
||||||
@@ -336,15 +379,22 @@
|
|||||||
</TextBox>
|
</TextBox>
|
||||||
<TextBlock FontSize="12" Text="{Binding Path}" />
|
<TextBlock FontSize="12" Text="{Binding Path}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<Button Grid.Column="2" x:Name="FilterButton" Style="{StaticResource NoBorderButtonStyle}" Height="50">
|
<Button Grid.Column="2" x:Name="SearchButton" Style="{StaticResource NoBorderButtonStyle}" Height="50">
|
||||||
<SymbolIcon Symbol="Filter" />
|
<SymbolIcon Symbol="Find" />
|
||||||
<Button.Flyout>
|
<Button.Flyout>
|
||||||
<Flyout>
|
<Flyout>
|
||||||
<controls:TextBoxWithButton x:Uid="GroupFilter" ButtonSymbol="" Text="{Binding Filter, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" FontSize="18" VerticalContentAlignment="Center" Width="400" Style="{StaticResource TextBoxWithButtonStyle}" IsButtonEnabled="False" />
|
<Flyout.FlyoutPresenterStyle>
|
||||||
|
<Style TargetType="FlyoutPresenter">
|
||||||
|
<Setter Property="Padding" Value="0" />
|
||||||
|
</Style>
|
||||||
|
</Flyout.FlyoutPresenterStyle>
|
||||||
|
<!--<controls:TextBoxWithButton x:Uid="GroupFilter" ButtonSymbol="" Text="{Binding Filter, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" FontSize="18" VerticalContentAlignment="Center" Width="400" Style="{StaticResource TextBoxWithButtonStyle}" IsButtonEnabled="False" />-->
|
||||||
|
<SearchBox x:Uid="GroupSearch" Width="350" Padding="12" Background="{ThemeResource TextBoxDisabledBackgroundThemeBrush}" BorderThickness="0" FontSize="18" SuggestionsRequested="SearchBox_OnSuggestionsRequested" SearchHistoryEnabled="False" ResultSuggestionChosen="SearchBox_OnResultSuggestionChosen" />
|
||||||
</Flyout>
|
</Flyout>
|
||||||
</Button.Flyout>
|
</Button.Flyout>
|
||||||
</Button>
|
</Button>
|
||||||
<controls:TextBoxWithButton Grid.Column="2" x:Name="FilterBox" x:Uid="GroupFilter" ButtonSymbol="" Text="{Binding Filter, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" FontSize="18" VerticalContentAlignment="Center" Width="400" Style="{StaticResource TextBoxWithButtonStyle}" IsButtonEnabled="False" />
|
<!--<controls:TextBoxWithButton Grid.Column="2" x:Name="FilterBox" x:Uid="GroupFilter" ButtonSymbol="" Text="{Binding Filter, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" FontSize="18" VerticalContentAlignment="Center" Width="400" Style="{StaticResource TextBoxWithButtonStyle}" IsButtonEnabled="False" />-->
|
||||||
|
<SearchBox Grid.Column="2" x:Uid="GroupSearch" x:Name="SearchBox" Padding="12" Width="350" Background="{ThemeResource TextBoxDisabledBackgroundThemeBrush}" BorderThickness="0" FontSize="18" SuggestionsRequested="SearchBox_OnSuggestionsRequested" SearchHistoryEnabled="False" ResultSuggestionChosen="SearchBox_OnResultSuggestionChosen" />
|
||||||
</Grid>
|
</Grid>
|
||||||
<VisualStateManager.VisualStateGroups>
|
<VisualStateManager.VisualStateGroups>
|
||||||
<VisualStateGroup x:Name="DragDropGroup">
|
<VisualStateGroup x:Name="DragDropGroup">
|
||||||
@@ -363,23 +413,23 @@
|
|||||||
</Storyboard>
|
</Storyboard>
|
||||||
</VisualState>
|
</VisualState>
|
||||||
</VisualStateGroup>
|
</VisualStateGroup>
|
||||||
<VisualStateGroup x:Name="FilterGroup">
|
<VisualStateGroup x:Name="SearchGroup">
|
||||||
<VisualState x:Name="Small">
|
<VisualState x:Name="Small">
|
||||||
<Storyboard>
|
<Storyboard>
|
||||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="FilterButton" Storyboard.TargetProperty="Visibility">
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SearchButton" Storyboard.TargetProperty="Visibility">
|
||||||
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
|
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
|
||||||
</ObjectAnimationUsingKeyFrames>
|
</ObjectAnimationUsingKeyFrames>
|
||||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="FilterBox" Storyboard.TargetProperty="Visibility">
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SearchBox" Storyboard.TargetProperty="Visibility">
|
||||||
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
|
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
|
||||||
</ObjectAnimationUsingKeyFrames>
|
</ObjectAnimationUsingKeyFrames>
|
||||||
</Storyboard>
|
</Storyboard>
|
||||||
</VisualState>
|
</VisualState>
|
||||||
<VisualState x:Name="Large">
|
<VisualState x:Name="Large">
|
||||||
<Storyboard>
|
<Storyboard>
|
||||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="FilterButton" Storyboard.TargetProperty="Visibility">
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SearchButton" Storyboard.TargetProperty="Visibility">
|
||||||
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
|
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
|
||||||
</ObjectAnimationUsingKeyFrames>
|
</ObjectAnimationUsingKeyFrames>
|
||||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="FilterBox" Storyboard.TargetProperty="Visibility">
|
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SearchBox" Storyboard.TargetProperty="Visibility">
|
||||||
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
|
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
|
||||||
</ObjectAnimationUsingKeyFrames>
|
</ObjectAnimationUsingKeyFrames>
|
||||||
</Storyboard>
|
</Storyboard>
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using Windows.ApplicationModel.DataTransfer;
|
using Windows.ApplicationModel.DataTransfer;
|
||||||
|
using Windows.Storage.Streams;
|
||||||
using Windows.UI.Xaml;
|
using Windows.UI.Xaml;
|
||||||
using Windows.UI.Xaml.Controls;
|
using Windows.UI.Xaml.Controls;
|
||||||
using Windows.UI.Xaml.Navigation;
|
using Windows.UI.Xaml.Navigation;
|
||||||
@@ -82,9 +84,6 @@ namespace ModernKeePass.Views
|
|||||||
{
|
{
|
||||||
case -1:
|
case -1:
|
||||||
return;
|
return;
|
||||||
case 0:
|
|
||||||
group = Model.AddNewGroup();
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
group = LeftListView.SelectedItem as GroupVm;
|
group = LeftListView.SelectedItem as GroupVm;
|
||||||
break;
|
break;
|
||||||
@@ -118,9 +117,9 @@ namespace ModernKeePass.Views
|
|||||||
resource.GetResourceValue("EntityDeleteCancelButton"), a =>
|
resource.GetResourceValue("EntityDeleteCancelButton"), a =>
|
||||||
{
|
{
|
||||||
ToastNotificationHelper.ShowMovedToast(Model, resource.GetResourceValue("EntityDeleting"), text);
|
ToastNotificationHelper.ShowMovedToast(Model, resource.GetResourceValue("EntityDeleting"), text);
|
||||||
Model.MarkForDelete();
|
Model.MarkForDelete(resource.GetResourceValue("RecycleBinTitle"));
|
||||||
if (Frame.CanGoBack) Frame.GoBack();
|
if (Frame.CanGoBack) Frame.GoBack();
|
||||||
});
|
}, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RestoreButton_Click(object sender, RoutedEventArgs e)
|
private void RestoreButton_Click(object sender, RoutedEventArgs e)
|
||||||
@@ -143,6 +142,10 @@ namespace ModernKeePass.Views
|
|||||||
{
|
{
|
||||||
Frame.Navigate(typeof(EntryDetailPage), Model.AddNewEntry());
|
Frame.Navigate(typeof(EntryDetailPage), Model.AddNewEntry());
|
||||||
}
|
}
|
||||||
|
private void CreateGroup_ButtonClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
Frame.Navigate(typeof(GroupDetailPage), Model.AddNewGroup());
|
||||||
|
}
|
||||||
|
|
||||||
private void GridView_DragItemsStarting(object sender, DragItemsStartingEventArgs e)
|
private void GridView_DragItemsStarting(object sender, DragItemsStartingEventArgs e)
|
||||||
{
|
{
|
||||||
@@ -150,6 +153,22 @@ namespace ModernKeePass.Views
|
|||||||
e.Data.RequestedOperation = DataPackageOperation.Move;
|
e.Data.RequestedOperation = DataPackageOperation.Move;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SearchBox_OnSuggestionsRequested(SearchBox sender, SearchBoxSuggestionsRequestedEventArgs args)
|
||||||
|
{
|
||||||
|
var imageUri = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx://Assets/ModernKeePass-SmallLogo.scale-80.png"));
|
||||||
|
var results = Model.Entries.Where(e => e.Name.IndexOf(args.QueryText, StringComparison.OrdinalIgnoreCase) >= 0).Take(5);
|
||||||
|
foreach (var result in results)
|
||||||
|
{
|
||||||
|
args.Request.SearchSuggestionCollection.AppendResultSuggestion(result.Name, result.ParentGroup.Name, result.Id, imageUri, string.Empty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SearchBox_OnResultSuggestionChosen(SearchBox sender, SearchBoxResultSuggestionChosenEventArgs args)
|
||||||
|
{
|
||||||
|
var entry = Model.Entries.FirstOrDefault(e => e.Id == args.Tag);
|
||||||
|
Frame.Navigate(typeof(EntryDetailPage), entry);
|
||||||
|
}
|
||||||
|
|
||||||
private void GroupDetailPage_OnSizeChanged(object sender, SizeChangedEventArgs e)
|
private void GroupDetailPage_OnSizeChanged(object sender, SizeChangedEventArgs e)
|
||||||
{
|
{
|
||||||
VisualStateManager.GoToState(this, e.NewSize.Width < 700 ? "Small" : "Large", true);
|
VisualStateManager.GoToState(this, e.NewSize.Width < 700 ? "Small" : "Large", true);
|
||||||
|
@@ -4,27 +4,6 @@
|
|||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:viewModels="using:ModernKeePass.ViewModels"
|
|
||||||
xmlns:converters="using:ModernKeePass.Converters"
|
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
<Page.DataContext>
|
<WebView Source="https://PayPal.Me/wismna"></WebView>
|
||||||
<viewModels:DonateVm />
|
|
||||||
</Page.DataContext>
|
|
||||||
<Page.Resources>
|
|
||||||
<converters:NullToBooleanConverter x:Key="NullToBooleanConverter"/>
|
|
||||||
<CollectionViewSource
|
|
||||||
x:Name="DonateItemsSource"
|
|
||||||
Source="{Binding Donations}" />
|
|
||||||
</Page.Resources>
|
|
||||||
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Margin="10,0,0,0">
|
|
||||||
<TextBlock x:Uid="DonateDesc" Style="{StaticResource BodyTextBlockStyle}" />
|
|
||||||
<ItemsControl ItemsSource="{Binding Source={StaticResource DonateItemsSource}}" Margin="0,10,0,10">
|
|
||||||
<ItemsControl.ItemTemplate>
|
|
||||||
<DataTemplate>
|
|
||||||
<RadioButton GroupName="DonateOptions" Content="{Binding FormattedPrice}" Checked="ToggleButton_OnChecked" />
|
|
||||||
</DataTemplate>
|
|
||||||
</ItemsControl.ItemTemplate>
|
|
||||||
</ItemsControl>
|
|
||||||
<Button x:Uid="DonateButton" Click="ButtonBase_OnClick" IsEnabled="{Binding SelectedItem, Converter={StaticResource NullToBooleanConverter}}" />
|
|
||||||
</StackPanel>
|
|
||||||
</Page>
|
</Page>
|
||||||
|
@@ -1,12 +1,4 @@
|
|||||||
using System;
|
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
|
||||||
using Windows.ApplicationModel.Store;
|
|
||||||
using Windows.UI.Xaml;
|
|
||||||
using Windows.UI.Xaml.Controls;
|
|
||||||
using ModernKeePass.Common;
|
|
||||||
using ModernKeePass.Services;
|
|
||||||
using ModernKeePass.ViewModels;
|
|
||||||
|
|
||||||
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
|
|
||||||
|
|
||||||
namespace ModernKeePass.Views
|
namespace ModernKeePass.Views
|
||||||
{
|
{
|
||||||
@@ -15,57 +7,9 @@ namespace ModernKeePass.Views
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed partial class DonatePage
|
public sealed partial class DonatePage
|
||||||
{
|
{
|
||||||
public DonateVm Model => DataContext as DonateVm;
|
|
||||||
|
|
||||||
public DonatePage()
|
public DonatePage()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ToggleButton_OnChecked(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
var source = sender as RadioButton;
|
|
||||||
Model.SelectedItem = source?.DataContext as ProductListing;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void ButtonBase_OnClick(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
var resource = new ResourcesService();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var result = await Model.Purchase();
|
|
||||||
switch ((LicenseService.PurchaseResult)result)
|
|
||||||
{
|
|
||||||
case LicenseService.PurchaseResult.Succeeded:
|
|
||||||
MessageDialogHelper.ShowNotificationDialog(resource.GetResourceValue("DonateSucceededTitle"), resource.GetResourceValue("DonateSucceededMessage"));
|
|
||||||
break;
|
|
||||||
case LicenseService.PurchaseResult.NothingToFulfill:
|
|
||||||
MessageDialogHelper.ShowNotificationDialog(resource.GetResourceValue("DonateNothingToFulfillTitle"), resource.GetResourceValue("DonateNothingToFulfillMessage"));
|
|
||||||
break;
|
|
||||||
case LicenseService.PurchaseResult.PurchasePending:
|
|
||||||
MessageDialogHelper.ShowNotificationDialog(resource.GetResourceValue("DonatePurchasePendingTitle"), resource.GetResourceValue("DonatePurchasePendingMessage"));
|
|
||||||
break;
|
|
||||||
case LicenseService.PurchaseResult.PurchaseReverted:
|
|
||||||
MessageDialogHelper.ShowNotificationDialog(resource.GetResourceValue("DonatePurchaseRevertedTitle"), resource.GetResourceValue("DonatePurchaseRevertedMessage"));
|
|
||||||
break;
|
|
||||||
case LicenseService.PurchaseResult.ServerError:
|
|
||||||
MessageDialogHelper.ShowNotificationDialog(resource.GetResourceValue("DonateServerErrorTitle"), resource.GetResourceValue("DonateServerErrorMessage"));
|
|
||||||
break;
|
|
||||||
case LicenseService.PurchaseResult.NotPurchased:
|
|
||||||
MessageDialogHelper.ShowNotificationDialog(resource.GetResourceValue("DonateNotPurchasedTitle"), resource.GetResourceValue("DonateNotPurchasedMessage"));
|
|
||||||
break;
|
|
||||||
// Should never happen because these are consumables
|
|
||||||
case LicenseService.PurchaseResult.AlreadyPurchased:
|
|
||||||
MessageDialogHelper.ShowNotificationDialog(resource.GetResourceValue("DonateAlreadyPurchasedTitle"), resource.GetResourceValue("DonateAlreadyPurchasedMessage"));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new ArgumentOutOfRangeException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception exception)
|
|
||||||
{
|
|
||||||
MessageDialogHelper.ShowErrorDialog(exception);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -28,10 +28,10 @@ namespace ModernKeePass.Views
|
|||||||
_mainFrame = e.Parameter as Frame;
|
_mainFrame = e.Parameter as Frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SaveButton_OnClick(object sender, RoutedEventArgs e)
|
private async void SaveButton_OnClick(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
Model.Save();
|
await Model.Save();
|
||||||
_mainFrame.Navigate(typeof(Views.MainPage));
|
_mainFrame.Navigate(typeof(MainPage));
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void SaveAsButton_OnClick(object sender, RoutedEventArgs e)
|
private async void SaveAsButton_OnClick(object sender, RoutedEventArgs e)
|
||||||
@@ -47,7 +47,7 @@ namespace ModernKeePass.Views
|
|||||||
if (file == null) return;
|
if (file == null) return;
|
||||||
Model.Save(file);
|
Model.Save(file);
|
||||||
|
|
||||||
_mainFrame.Navigate(typeof(Views.MainPage));
|
_mainFrame.Navigate(typeof(MainPage));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,13 +5,15 @@
|
|||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:viewModels="using:ModernKeePass.ViewModels"
|
xmlns:viewModels="using:ModernKeePass.ViewModels"
|
||||||
xmlns:templateSelectors="using:ModernKeePass.TemplateSelectors"
|
xmlns:converters="using:ModernKeePass.Converters"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
<Page.Resources>
|
<Page.Resources>
|
||||||
<CollectionViewSource x:Name="RecycleBinGroups" Source="{Binding Groups}" />
|
<CollectionViewSource x:Name="RecycleBinGroups" Source="{Binding Groups}" />
|
||||||
<CollectionViewSource x:Name="Ciphers" Source="{Binding Ciphers}" />
|
<CollectionViewSource x:Name="Ciphers" Source="{Binding Ciphers}" />
|
||||||
<CollectionViewSource x:Name="Compressions" Source="{Binding Compressions}" />
|
<CollectionViewSource x:Name="Compressions" Source="{Binding Compressions}" />
|
||||||
<CollectionViewSource x:Name="KeyDerivations" Source="{Binding KeyDerivations}" />
|
<CollectionViewSource x:Name="KeyDerivations" Source="{Binding KeyDerivations}" />
|
||||||
|
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
|
||||||
|
<converters:NullToBooleanConverter x:Key="NullToBooleanConverter"/>
|
||||||
</Page.Resources>
|
</Page.Resources>
|
||||||
<Page.DataContext>
|
<Page.DataContext>
|
||||||
<viewModels:SettingsDatabaseVm />
|
<viewModels:SettingsDatabaseVm />
|
||||||
@@ -19,21 +21,11 @@
|
|||||||
|
|
||||||
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||||
<ToggleSwitch x:Uid="SettingsDatabaseRecycleBin" IsOn="{Binding HasRecycleBin, Mode=TwoWay}" />
|
<ToggleSwitch x:Uid="SettingsDatabaseRecycleBin" IsOn="{Binding HasRecycleBin, Mode=TwoWay}" />
|
||||||
<ComboBox ItemsSource="{Binding Source={StaticResource RecycleBinGroups}}" SelectedItem="{Binding SelectedItem, Mode=TwoWay}" IsEnabled="{Binding HasRecycleBin}">
|
<StackPanel Visibility="{Binding HasRecycleBin, Converter={StaticResource BooleanToVisibilityConverter}}">
|
||||||
<ComboBox.Resources>
|
<RadioButton x:Uid="SettingsDatabaseRecycleBinCreate" GroupName="Recycle" IsChecked="{Binding IsNewRecycleBin, Mode=TwoWay}" />
|
||||||
<DataTemplate x:Name="GroupFirstItem">
|
<RadioButton x:Name="RadioButton" x:Uid="SettingsDatabaseRecycleBinExisting" GroupName="Recycle" IsChecked="{Binding SelectedItem, Converter={StaticResource NullToBooleanConverter}}" />
|
||||||
<TextBlock x:Uid="GroupNewItemTextBox" />
|
<ComboBox ItemsSource="{Binding Source={StaticResource RecycleBinGroups}}" SelectedItem="{Binding SelectedItem, Mode=TwoWay}" IsEnabled="{Binding IsChecked, ElementName=RadioButton}" />
|
||||||
</DataTemplate>
|
</StackPanel>
|
||||||
<DataTemplate x:Name="GroupOtherItem">
|
|
||||||
<TextBlock Text="{Binding}" />
|
|
||||||
</DataTemplate>
|
|
||||||
</ComboBox.Resources>
|
|
||||||
<ComboBox.ItemTemplateSelector>
|
|
||||||
<templateSelectors:FirstItemDataTemplateSelector
|
|
||||||
FirstItem="{StaticResource GroupFirstItem}"
|
|
||||||
OtherItem="{StaticResource GroupOtherItem}" />
|
|
||||||
</ComboBox.ItemTemplateSelector>
|
|
||||||
</ComboBox>
|
|
||||||
<TextBlock x:Uid="SettingsDatabaseEncryption" Style="{StaticResource TextBlockSettingsHeaderStyle}" Margin="5,20,0,10" />
|
<TextBlock x:Uid="SettingsDatabaseEncryption" Style="{StaticResource TextBlockSettingsHeaderStyle}" Margin="5,20,0,10" />
|
||||||
<ComboBox ItemsSource="{Binding Source={StaticResource Ciphers}}" SelectedIndex="{Binding CipherIndex, Mode=TwoWay}" />
|
<ComboBox ItemsSource="{Binding Source={StaticResource Ciphers}}" SelectedIndex="{Binding CipherIndex, Mode=TwoWay}" />
|
||||||
<TextBlock x:Uid="SettingsDatabaseCompression" Style="{StaticResource TextBlockSettingsHeaderStyle}" Margin="5,20,0,10" />
|
<TextBlock x:Uid="SettingsDatabaseCompression" Style="{StaticResource TextBlockSettingsHeaderStyle}" Margin="5,20,0,10" />
|
||||||
|
18
ModernKeePass/Views/SettingsPageFrames/SettingsSavePage.xaml
Normal file
18
ModernKeePass/Views/SettingsPageFrames/SettingsSavePage.xaml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<Page
|
||||||
|
x:Class="ModernKeePass.Views.SettingsSavePage"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:viewModels="using:ModernKeePass.ViewModels"
|
||||||
|
mc:Ignorable="d">
|
||||||
|
<Page.DataContext>
|
||||||
|
<viewModels:SettingsSaveVm />
|
||||||
|
</Page.DataContext>
|
||||||
|
|
||||||
|
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||||
|
<TextBlock x:Uid="SettingsSaveDatabaseSuspendTitle" Style="{StaticResource TextBlockSettingsHeaderStyle}" Margin="5,0,0,10"/>
|
||||||
|
<TextBlock x:Uid="SettingsSaveDatabaseSuspendDesc" TextWrapping="WrapWholeWords" Margin="5,0,0,10"/>
|
||||||
|
<ToggleSwitch x:Uid="SettingsSaveDatabaseSuspend" IsOn="{Binding IsSaveSuspend, Mode=TwoWay}" />
|
||||||
|
</StackPanel>
|
||||||
|
</Page>
|
@@ -0,0 +1,15 @@
|
|||||||
|
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
|
||||||
|
|
||||||
|
namespace ModernKeePass.Views
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An empty page that can be used on its own or navigated to within a Frame.
|
||||||
|
/// </summary>
|
||||||
|
public sealed partial class SettingsSavePage
|
||||||
|
{
|
||||||
|
public SettingsSavePage()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -2,7 +2,6 @@
|
|||||||
x:Class="ModernKeePass.Views.SettingsSecurityPage"
|
x:Class="ModernKeePass.Views.SettingsSecurityPage"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:local="using:ModernKeePass.Controls"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:userControls="using:ModernKeePass.Views.UserControls"
|
xmlns:userControls="using:ModernKeePass.Views.UserControls"
|
||||||
|
@@ -11,7 +11,6 @@
|
|||||||
xmlns:viewModels="using:ModernKeePass.ViewModels"
|
xmlns:viewModels="using:ModernKeePass.ViewModels"
|
||||||
mc:Ignorable="d" >
|
mc:Ignorable="d" >
|
||||||
<UserControl.Resources>
|
<UserControl.Resources>
|
||||||
<SolidColorBrush x:Key="ErrorColorBrush" Color="Red"/>
|
|
||||||
<converters:ProgressBarLegalValuesConverter x:Key="ProgressBarLegalValuesConverter"/>
|
<converters:ProgressBarLegalValuesConverter x:Key="ProgressBarLegalValuesConverter"/>
|
||||||
<converters:DoubleToSolidColorBrushConverter x:Key="DoubleToForegroungBrushConverter"/>
|
<converters:DoubleToSolidColorBrushConverter x:Key="DoubleToForegroungBrushConverter"/>
|
||||||
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
|
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
|
||||||
@@ -55,7 +54,7 @@
|
|||||||
</ToolTipService.ToolTip>
|
</ToolTipService.ToolTip>
|
||||||
</SymbolIcon>
|
</SymbolIcon>
|
||||||
</HyperlinkButton>
|
</HyperlinkButton>
|
||||||
<TextBlock Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="3" Height="28" FontSize="14" FontWeight="Light" Text="{Binding Status}" Foreground="{Binding StatusType, Converter={StaticResource DiscreteIntToSolidColorBrushConverter}}" Visibility="{Binding Status, Converter={StaticResource EmptyStringToVisibilityConverter}}" />
|
|
||||||
<Button Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="2" Content="{Binding ButtonLabel, ElementName=UserControl}" Click="OpenButton_OnClick" Background="{ThemeResource ListViewItemSelectedPointerOverBorderThemeBrush}" Foreground="{ThemeResource TextBoxBackgroundThemeBrush}" IsEnabled="{Binding IsValid}" />
|
<Button Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="2" Content="{Binding ButtonLabel, ElementName=UserControl}" Click="OpenButton_OnClick" Background="{ThemeResource ListViewItemSelectedPointerOverBorderThemeBrush}" Foreground="{ThemeResource TextBoxBackgroundThemeBrush}" IsEnabled="{Binding IsValid}" />
|
||||||
|
<TextBlock Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="3" Height="28" FontSize="14" FontWeight="Light" Text="{Binding Status}" Foreground="{Binding StatusType, Converter={StaticResource DiscreteIntToSolidColorBrushConverter}}" Visibility="{Binding Status, Converter={StaticResource EmptyStringToVisibilityConverter}}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
@@ -90,7 +90,12 @@ namespace ModernKeePass.Views.UserControls
|
|||||||
|
|
||||||
private void PasswordBox_KeyDown(object sender, KeyRoutedEventArgs e)
|
private void PasswordBox_KeyDown(object sender, KeyRoutedEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.Key == VirtualKey.Enter && Model.IsValid) OpenButton_OnClick(null, null);
|
if (e.Key == VirtualKey.Enter && Model.IsValid)
|
||||||
|
{
|
||||||
|
OpenButton_OnClick(sender, e);
|
||||||
|
// Stop the event from triggering twice
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void KeyFileButton_Click(object sender, RoutedEventArgs e)
|
private async void KeyFileButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
@@ -1,11 +1,4 @@
|
|||||||
You can now reorder entries
|
Application now correctly resumes from suspend
|
||||||
Entries and groups are sortable
|
Code enhancements
|
||||||
New Home button that allows returning to the main menu from anywhere
|
Return of the Donate page, with Paypal
|
||||||
Change default database creation settings
|
KeePassLib version bump to 2.38
|
||||||
Settings is accessible from main menu
|
|
||||||
Clear Recent databases
|
|
||||||
New French translation
|
|
||||||
Better layout whith small screen size
|
|
||||||
Search becomes Filter
|
|
||||||
Design and usability improvements
|
|
||||||
Bugs correction
|
|
@@ -1,6 +1,6 @@
|
|||||||
En avez-vous assez d'essayer de retenir des quantit<EFBFBD>s de mots de passe ? Etes-vous soucieux que le fait d'utiliser le m<EFBFBD>me mot de passe partout vous rend vuln<EFBFBD>rable ?
|
En avez-vous assez d'essayer de retenir des quantites de mots de passe ? Etes-vous soucieux que le fait d'utiliser le meme mot de passe partout vous rend vulnerable ?
|
||||||
ModernKeePass est un gestionnaire de mots de passe gratuit, libre, facile <EFBFBD> utiliser mais n<EFBFBD>anmoins s<EFBFBD>r, bas<EFBFBD> sur la technologie certifi<EFBFBD>e et r<EFBFBD>pandue KeePass 2.x et compatible avec celui-ci.
|
ModernKeePass est un gestionnaire de mots de passe gratuit, libre, facile a utiliser mais neanmoins sur, base sur la technologie certifiee et repandue KeePass 2.x et compatible avec celui-ci.
|
||||||
Vous pouvez stocker ou g<EFBFBD>n<EFBFBD>rer vos mots de passe dans une base de donn<EFBFBD>es chiffr<EFBFBD>e, qui peut <EFBFBD>tre plac<EFBFBD>e n'importe o<EFBFBD> (ordinateur personel/tablette, cloud, cl<EFBFBD> USB...)
|
Vous pouvez stocker ou generer vos mots de passe dans une base de donnees chiffree, qui peut etre placee n'importe ou (ordinateur personnel/tablette, cloud, cle USB...)
|
||||||
|
|
||||||
Bien que la s<EFBFBD>curit<EFBFBD> informatique soit tr<EFBFBD>s importante, cette application essaie de rester simple <EFBFBD> utiliser et <EFBFBD> comprendre. Vos suggestions sont les bienvenues !
|
Bien que la securite informatique soit tres importante, cette application essaie de rester simple a utiliser et a comprendre. Vos suggestions sont les bienvenues !
|
||||||
Fonctionne sur Windows 10, 8.1 et RT.
|
Fonctionne sur Windows 10, 8.1 et RT.
|
@@ -1 +1 @@
|
|||||||
Page d'entr<EFBFBD>e avec g<EFBFBD>n<EFBFBD>rateur de mot de passe
|
Page d'entree avec generateur de mot de passe
|
@@ -1 +1 @@
|
|||||||
Filtrez vos entr<EFBFBD>es pour rapidement trouver celle qui vous int<EFBFBD>resse
|
Filtrez vos entrees pour rapidement trouver celle qui vous interesse
|
@@ -1 +1 @@
|
|||||||
Vue d'un groupe, avec ses sous-groupes et ses entr<EFBFBD>es
|
Vue d'un groupe, avec ses sous-groupes et ses entrees
|
@@ -1 +1 @@
|
|||||||
Cr<EFBFBD>ez de nouvelles bases de donn<EFBFBD>es, en d<EFBFBD>finissant un mot de passe et/ou un fichier de cl<EFBFBD> existant ou nouveau
|
Creez de nouvelles bases de donnees, en definissant un mot de passe et/ou un fichier de cle existant ou nouveau
|
@@ -1 +1 @@
|
|||||||
Ouvrez une base de donn<EFBFBD>es avec mot de passe et/ou fichier de cl<EFBFBD>
|
Ouvrez une base de donnees avec mot de passe et/ou fichier de cle
|
@@ -1 +1 @@
|
|||||||
Ouvrez les fichiers r<EFBFBD>cents
|
Ouvrez les fichiers recents
|
@@ -1 +1 @@
|
|||||||
Vue d'ensemble avec le zoom s<EFBFBD>mantique
|
Vue d'ensemble avec le zoom semantique
|
@@ -1 +1 @@
|
|||||||
Param<EFBFBD>tres de l'application
|
Parametres de l'application
|
@@ -1,11 +1,4 @@
|
|||||||
Vous pouvez d<>sormais r<>organiser vos entr<74>es
|
L'application recupere correctement d'une suspension
|
||||||
Les entr<74>es et les groupes peuvent <20>tre tri<72>s
|
Ameliorations de code
|
||||||
Nouveau bouton d'Accueil qui permet de retourner au menu principal
|
Retour de la page de donation, avec Paypal
|
||||||
Changez les options de cr<EFBFBD>ation des nouvelles bases de donn<6E>es
|
Version de la KeePassLib montee a 2.38
|
||||||
Les param<61>tres sont accessibles depuis le menu principal
|
|
||||||
Effacez les <20>l<EFBFBD>ments r<>cents
|
|
||||||
Traduction fran<61>aise
|
|
||||||
Meilleur rendu en petit <20>cran
|
|
||||||
La recherche devient Filtre
|
|
||||||
Am<EFBFBD>liorations de design et d'ergonomie
|
|
||||||
Corrections de bogues
|
|
@@ -1,10 +1,13 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
|
<package id="Microsoft.AppCenter" version="1.5.0" targetFramework="win81" />
|
||||||
|
<package id="Microsoft.AppCenter.Analytics" version="1.5.0" targetFramework="win81" />
|
||||||
|
<package id="Microsoft.AppCenter.Push" version="1.5.0" targetFramework="win81" />
|
||||||
<package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="win81" />
|
<package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="win81" />
|
||||||
<package id="Microsoft.NETCore.Platforms" version="2.0.1" targetFramework="win81" />
|
<package id="Microsoft.NETCore.Platforms" version="2.0.1" targetFramework="win81" />
|
||||||
<package id="Microsoft.NETCore.Portable.Compatibility" version="1.0.2" targetFramework="win81" />
|
<package id="Microsoft.NETCore.Portable.Compatibility" version="1.0.2" targetFramework="win81" />
|
||||||
<package id="Microsoft.Toolkit.Uwp.Notifications" version="2.0.0" targetFramework="win81" />
|
<package id="Microsoft.Toolkit.Uwp.Notifications" version="2.0.0" targetFramework="win81" />
|
||||||
<package id="ModernKeePassLib" version="2.37.8000" targetFramework="win81" />
|
<package id="ModernKeePassLib" version="2.38.2" targetFramework="win81" />
|
||||||
<package id="NETStandard.Library" version="2.0.1" targetFramework="win81" />
|
<package id="NETStandard.Library" version="2.0.1" targetFramework="win81" />
|
||||||
<package id="Portable.BouncyCastle" version="1.8.1.3" targetFramework="win81" />
|
<package id="Portable.BouncyCastle" version="1.8.1.3" targetFramework="win81" />
|
||||||
<package id="Splat" version="2.0.0" targetFramework="win81" />
|
<package id="Splat" version="2.0.0" targetFramework="win81" />
|
||||||
|
@@ -16,20 +16,20 @@ namespace ModernKeePassApp.Test
|
|||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void TestCreate()
|
public void TestCreate()
|
||||||
{
|
{
|
||||||
Assert.AreEqual((int) DatabaseService.DatabaseStatus.Closed, _database.Status);
|
Assert.IsTrue(_database.IsClosed);
|
||||||
_database.DatabaseFile = ApplicationData.Current.TemporaryFolder.CreateFileAsync("NewDatabase.kdbx").GetAwaiter().GetResult();
|
_database.DatabaseFile = ApplicationData.Current.TemporaryFolder.CreateFileAsync("NewDatabase.kdbx").GetAwaiter().GetResult();
|
||||||
Assert.AreEqual((int)DatabaseService.DatabaseStatus.Opening, _database.Status);
|
Assert.IsTrue(_database.IsFileOpen);
|
||||||
OpenOrCreateDatabase(true);
|
OpenOrCreateDatabase(true);
|
||||||
_database.Close();
|
_database.Close().GetAwaiter().GetResult();
|
||||||
Assert.AreEqual((int)DatabaseService.DatabaseStatus.Closed, _database.Status);
|
Assert.IsTrue(_database.IsClosed);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void TestOpen()
|
public void TestOpen()
|
||||||
{
|
{
|
||||||
Assert.AreEqual((int)DatabaseService.DatabaseStatus.Closed, _database.Status);
|
Assert.IsTrue(_database.IsClosed);
|
||||||
_database.DatabaseFile = Package.Current.InstalledLocation.GetFileAsync(@"Databases\TestDatabase.kdbx").GetAwaiter().GetResult();
|
_database.DatabaseFile = Package.Current.InstalledLocation.GetFileAsync(@"Data\TestDatabase.kdbx").GetAwaiter().GetResult();
|
||||||
Assert.AreEqual((int)DatabaseService.DatabaseStatus.Opening, _database.Status);
|
Assert.IsTrue(_database.IsFileOpen);
|
||||||
OpenOrCreateDatabase(false);
|
OpenOrCreateDatabase(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,23 +38,23 @@ namespace ModernKeePassApp.Test
|
|||||||
{
|
{
|
||||||
TestOpen();
|
TestOpen();
|
||||||
_database.Save(ApplicationData.Current.TemporaryFolder.CreateFileAsync("SaveDatabase.kdbx").GetAwaiter().GetResult());
|
_database.Save(ApplicationData.Current.TemporaryFolder.CreateFileAsync("SaveDatabase.kdbx").GetAwaiter().GetResult());
|
||||||
Assert.AreEqual((int)DatabaseService.DatabaseStatus.Opened, _database.Status);
|
Assert.IsTrue(_database.IsOpen);
|
||||||
_database.Close();
|
_database.Close().GetAwaiter().GetResult();
|
||||||
Assert.AreEqual((int)DatabaseService.DatabaseStatus.Closed, _database.Status);
|
Assert.IsTrue(_database.IsClosed);
|
||||||
TestOpen();
|
TestOpen();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OpenOrCreateDatabase(bool createNew)
|
private void OpenOrCreateDatabase(bool createNew)
|
||||||
{
|
{
|
||||||
_database.Open(null, createNew);
|
Assert.ThrowsException<ArgumentNullException>(
|
||||||
Assert.AreEqual((int)DatabaseService.DatabaseStatus.NoCompositeKey, _database.Status);
|
() => _database.Open(null, createNew).GetAwaiter().GetResult());
|
||||||
var compositeKey = new CompositeKeyVm(_database, new ResourceServiceMock())
|
var compositeKey = new CompositeKeyVm(_database, new ResourceServiceMock())
|
||||||
{
|
{
|
||||||
HasPassword = true,
|
HasPassword = true,
|
||||||
Password = "test"
|
Password = "test"
|
||||||
};
|
};
|
||||||
compositeKey.OpenDatabase(createNew).GetAwaiter().GetResult();
|
compositeKey.OpenDatabase(createNew).GetAwaiter().GetResult();
|
||||||
Assert.AreEqual((int)DatabaseService.DatabaseStatus.Opened, _database.Status);
|
Assert.IsTrue(_database.IsOpen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using ModernKeePass.Interfaces;
|
using ModernKeePass.Interfaces;
|
||||||
using ModernKeePass.ViewModels;
|
using ModernKeePass.ViewModels;
|
||||||
using ModernKeePassLib;
|
using ModernKeePassLib;
|
||||||
@@ -8,16 +9,34 @@ using Windows.Storage;
|
|||||||
|
|
||||||
namespace ModernKeePassApp.Test.Mock
|
namespace ModernKeePassApp.Test.Mock
|
||||||
{
|
{
|
||||||
public class DatabaseServiceMock : IDatabase
|
public class DatabaseServiceMock : IDatabaseService
|
||||||
{
|
{
|
||||||
|
private bool _isOpen;
|
||||||
|
private bool _isClosed;
|
||||||
|
private CompositeKey _compositeKey;
|
||||||
|
|
||||||
public PwCompressionAlgorithm CompressionAlgorithm { get; set; }
|
public PwCompressionAlgorithm CompressionAlgorithm { get; set; }
|
||||||
|
|
||||||
public StorageFile DatabaseFile { get; set; }
|
public StorageFile DatabaseFile { get; set; }
|
||||||
|
|
||||||
|
public CompositeKey CompositeKey
|
||||||
|
{
|
||||||
|
get { return _compositeKey; }
|
||||||
|
set { _compositeKey = value; }
|
||||||
|
}
|
||||||
|
|
||||||
public PwUuid DataCipher { get; set; }
|
public PwUuid DataCipher { get; set; }
|
||||||
|
|
||||||
public KdfParameters KeyDerivation { get; set; }
|
public KdfParameters KeyDerivation { get; set; }
|
||||||
|
|
||||||
|
public bool IsOpen => _isOpen;
|
||||||
|
|
||||||
|
public bool IsFileOpen => DatabaseFile != null;
|
||||||
|
|
||||||
|
public bool IsClosed => _isClosed;
|
||||||
|
|
||||||
|
public bool HasChanged { get; set; }
|
||||||
|
|
||||||
public string Name => "MockDatabase";
|
public string Name => "MockDatabase";
|
||||||
|
|
||||||
public GroupVm RecycleBin { get; set; }
|
public GroupVm RecycleBin { get; set; }
|
||||||
@@ -26,41 +45,48 @@ namespace ModernKeePassApp.Test.Mock
|
|||||||
|
|
||||||
public GroupVm RootGroup { get; set; }
|
public GroupVm RootGroup { get; set; }
|
||||||
|
|
||||||
public int Status { get; set; }
|
|
||||||
|
|
||||||
public void AddDeletedItem(PwUuid id)
|
public void AddDeletedItem(PwUuid id)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Close()
|
public Task Close(bool releaseFile = true)
|
||||||
{
|
{
|
||||||
Status = 0;
|
return Task.Run(() =>
|
||||||
|
{
|
||||||
|
_isClosed = true;
|
||||||
|
_isOpen = false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CreateRecycleBin()
|
public void CreateRecycleBin(string title)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Open(CompositeKey key, bool createNew)
|
public Task Open(CompositeKey key, bool createNew = false)
|
||||||
{
|
{
|
||||||
Status = 2;
|
_compositeKey = key;
|
||||||
|
return Task.Run(() =>
|
||||||
|
{
|
||||||
|
_isOpen = true;
|
||||||
|
_isClosed = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task ReOpen()
|
||||||
|
{
|
||||||
|
await Open(_compositeKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Save()
|
public void Save()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
// Do Nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Save(StorageFile file)
|
public void Save(StorageFile file)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateCompositeKey(CompositeKey key)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
31
ModernKeePassApp.Test/Mock/LicenseServiceMock.cs
Normal file
31
ModernKeePassApp.Test/Mock/LicenseServiceMock.cs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Windows.ApplicationModel;
|
||||||
|
using Windows.ApplicationModel.Store;
|
||||||
|
using ModernKeePass.Interfaces;
|
||||||
|
|
||||||
|
namespace ModernKeePassApp.Test.Mock
|
||||||
|
{
|
||||||
|
public class LicenseServiceMock: ILicenseService
|
||||||
|
{
|
||||||
|
public IReadOnlyDictionary<string, ProductListing> Products { get; }
|
||||||
|
|
||||||
|
public LicenseServiceMock()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var proxyFile = Package.Current.InstalledLocation.GetFileAsync("data\\WindowsStoreProxy.xml").GetAwaiter().GetResult();
|
||||||
|
CurrentAppSimulator.ReloadSimulatorAsync(proxyFile).GetAwaiter().GetResult();
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
var listing = CurrentAppSimulator.LoadListingInformationAsync().GetAwaiter().GetResult();
|
||||||
|
Products = listing.ProductListings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<int> Purchase(string addOn)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -6,7 +6,7 @@ using Windows.Storage;
|
|||||||
|
|
||||||
namespace ModernKeePassApp.Test.Mock
|
namespace ModernKeePassApp.Test.Mock
|
||||||
{
|
{
|
||||||
class RecentServiceMock : IRecent
|
class RecentServiceMock : IRecentService
|
||||||
{
|
{
|
||||||
public int EntryCount => 0;
|
public int EntryCount => 0;
|
||||||
|
|
||||||
|
@@ -1,9 +1,8 @@
|
|||||||
using System;
|
using ModernKeePass.Interfaces;
|
||||||
using ModernKeePass.Interfaces;
|
|
||||||
|
|
||||||
namespace ModernKeePassApp.Test.Mock
|
namespace ModernKeePassApp.Test.Mock
|
||||||
{
|
{
|
||||||
class ResourceServiceMock : IResource
|
class ResourceServiceMock : IResourceService
|
||||||
{
|
{
|
||||||
public string GetResourceValue(string key)
|
public string GetResourceValue(string key)
|
||||||
{
|
{
|
||||||
|
@@ -3,11 +3,11 @@ using ModernKeePass.Interfaces;
|
|||||||
|
|
||||||
namespace ModernKeePassApp.Test.Mock
|
namespace ModernKeePassApp.Test.Mock
|
||||||
{
|
{
|
||||||
public class SettingsServiceMock : ISettings
|
public class SettingsServiceMock : ISettingsService
|
||||||
{
|
{
|
||||||
public T GetSetting<T>(string property)
|
public T GetSetting<T>(string property, T defaultValue = default(T))
|
||||||
{
|
{
|
||||||
return default(T);
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PutSetting<T>(string property, T value)
|
public void PutSetting<T>(string property, T value)
|
||||||
|
@@ -121,6 +121,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="DatabaseTests.cs" />
|
<Compile Include="DatabaseTests.cs" />
|
||||||
<Compile Include="Mock\DatabaseServiceMock.cs" />
|
<Compile Include="Mock\DatabaseServiceMock.cs" />
|
||||||
|
<Compile Include="Mock\LicenseServiceMock.cs" />
|
||||||
<Compile Include="Mock\RecentServiceMock.cs" />
|
<Compile Include="Mock\RecentServiceMock.cs" />
|
||||||
<Compile Include="Mock\ResourceServiceMock.cs" />
|
<Compile Include="Mock\ResourceServiceMock.cs" />
|
||||||
<Compile Include="Mock\SettingsServiceMock.cs" />
|
<Compile Include="Mock\SettingsServiceMock.cs" />
|
||||||
@@ -131,11 +132,14 @@
|
|||||||
<AppxManifest Include="Package.appxmanifest">
|
<AppxManifest Include="Package.appxmanifest">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</AppxManifest>
|
</AppxManifest>
|
||||||
<Content Include="Databases\TestDatabase.kdbx" />
|
<Content Include="Data\TestDatabase.kdbx" />
|
||||||
<None Include="ModernKeePassApp.Test_TemporaryKey.pfx" />
|
<None Include="ModernKeePassApp.Test_TemporaryKey.pfx" />
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Content Include="Data\WindowsStoreProxy.xml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Content>
|
||||||
<Content Include="Images\UnitTestLogo.scale-100.png">
|
<Content Include="Images\UnitTestLogo.scale-100.png">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
@@ -6,14 +6,15 @@ using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
|
|||||||
using ModernKeePass.ViewModels;
|
using ModernKeePass.ViewModels;
|
||||||
using ModernKeePass.Views;
|
using ModernKeePass.Views;
|
||||||
using ModernKeePassApp.Test.Mock;
|
using ModernKeePassApp.Test.Mock;
|
||||||
|
using ModernKeePassLib;
|
||||||
|
|
||||||
namespace ModernKeePassApp.Test
|
namespace ModernKeePassApp.Test
|
||||||
{
|
{
|
||||||
[TestClass]
|
[TestClass]
|
||||||
public class ViewModelsTests
|
public class ViewModelsTests
|
||||||
{
|
{
|
||||||
private RecentServiceMock _recent = new RecentServiceMock();
|
private readonly RecentServiceMock _recent = new RecentServiceMock();
|
||||||
private ResourceServiceMock _resource = new ResourceServiceMock();
|
private readonly ResourceServiceMock _resource = new ResourceServiceMock();
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void TestAboutVm()
|
public void TestAboutVm()
|
||||||
@@ -32,12 +33,13 @@ namespace ModernKeePassApp.Test
|
|||||||
var firstGroup = mainVm.MainMenuItems.FirstOrDefault();
|
var firstGroup = mainVm.MainMenuItems.FirstOrDefault();
|
||||||
Assert.AreEqual(7, firstGroup.Count());
|
Assert.AreEqual(7, firstGroup.Count());
|
||||||
|
|
||||||
database.Status = 1;
|
database.DatabaseFile = Package.Current.InstalledLocation.GetFileAsync(@"Data\TestDatabase.kdbx")
|
||||||
|
.GetAwaiter().GetResult();
|
||||||
mainVm = new MainVm(null, null, database, _resource, _recent);
|
mainVm = new MainVm(null, null, database, _resource, _recent);
|
||||||
Assert.IsNotNull(mainVm.SelectedItem);
|
Assert.IsNotNull(mainVm.SelectedItem);
|
||||||
Assert.AreEqual(typeof(OpenDatabasePage), ((MainMenuItemVm) mainVm.SelectedItem).PageType);
|
Assert.AreEqual(typeof(OpenDatabasePage), ((MainMenuItemVm) mainVm.SelectedItem).PageType);
|
||||||
|
|
||||||
database.Status = 2;
|
database.Open(null, false).GetAwaiter().GetResult();
|
||||||
mainVm = new MainVm(null, null, database, _resource, _recent);
|
mainVm = new MainVm(null, null, database, _resource, _recent);
|
||||||
Assert.IsNotNull(mainVm.SelectedItem);
|
Assert.IsNotNull(mainVm.SelectedItem);
|
||||||
Assert.AreEqual(2, mainVm.MainMenuItems.Count());
|
Assert.AreEqual(2, mainVm.MainMenuItems.Count());
|
||||||
@@ -61,8 +63,7 @@ namespace ModernKeePassApp.Test
|
|||||||
{
|
{
|
||||||
var database = new DatabaseServiceMock
|
var database = new DatabaseServiceMock
|
||||||
{
|
{
|
||||||
Status = 1,
|
DatabaseFile = Package.Current.InstalledLocation.GetFileAsync(@"Data\TestDatabase.kdbx")
|
||||||
DatabaseFile = Package.Current.InstalledLocation.GetFileAsync(@"Databases\TestDatabase.kdbx")
|
|
||||||
.GetAwaiter().GetResult()
|
.GetAwaiter().GetResult()
|
||||||
};
|
};
|
||||||
var openVm = new OpenVm(database);
|
var openVm = new OpenVm(database);
|
||||||
@@ -79,7 +80,7 @@ namespace ModernKeePassApp.Test
|
|||||||
public void TestRecentVm()
|
public void TestRecentVm()
|
||||||
{
|
{
|
||||||
var mru = StorageApplicationPermissions.MostRecentlyUsedList;
|
var mru = StorageApplicationPermissions.MostRecentlyUsedList;
|
||||||
mru.Add(Package.Current.InstalledLocation.GetFileAsync(@"Databases\TestDatabase.kdbx")
|
mru.Add(Package.Current.InstalledLocation.GetFileAsync(@"Data\TestDatabase.kdbx")
|
||||||
.GetAwaiter().GetResult(), "MockDatabase");
|
.GetAwaiter().GetResult(), "MockDatabase");
|
||||||
var recentVm = new RecentVm();
|
var recentVm = new RecentVm();
|
||||||
Assert.IsTrue(recentVm.RecentItems.Count == 1);
|
Assert.IsTrue(recentVm.RecentItems.Count == 1);
|
||||||
@@ -88,10 +89,17 @@ namespace ModernKeePassApp.Test
|
|||||||
mru.Clear();
|
mru.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*[TestMethod]
|
[TestMethod]
|
||||||
public void TestSaveVm()
|
public void TestSaveVm()
|
||||||
{
|
{
|
||||||
}*/
|
var database = new DatabaseServiceMock();
|
||||||
|
var saveVm = new SaveVm(database);
|
||||||
|
database.Open(null, false).GetAwaiter().GetResult();
|
||||||
|
saveVm.Save(false).GetAwaiter().GetResult();
|
||||||
|
Assert.IsTrue(database.IsOpen);
|
||||||
|
saveVm.Save().GetAwaiter().GetResult();
|
||||||
|
Assert.IsFalse(database.IsOpen);
|
||||||
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void TestSettingsVm()
|
public void TestSettingsVm()
|
||||||
@@ -100,10 +108,32 @@ namespace ModernKeePassApp.Test
|
|||||||
Assert.AreEqual(1, settingsVm.MenuItems.Count());
|
Assert.AreEqual(1, settingsVm.MenuItems.Count());
|
||||||
var firstGroup = settingsVm.MenuItems.FirstOrDefault();
|
var firstGroup = settingsVm.MenuItems.FirstOrDefault();
|
||||||
// All groups have an empty title, so all settings are put inside the empty group
|
// All groups have an empty title, so all settings are put inside the empty group
|
||||||
Assert.AreEqual(3, firstGroup.Count());
|
Assert.AreEqual(4, firstGroup.Count());
|
||||||
Assert.IsNotNull(settingsVm.SelectedItem);
|
Assert.IsNotNull(settingsVm.SelectedItem);
|
||||||
var selectedItem = (ListMenuItemVm) settingsVm.SelectedItem;
|
var selectedItem = (ListMenuItemVm) settingsVm.SelectedItem;
|
||||||
Assert.AreEqual(typeof(SettingsNewDatabasePage), selectedItem.PageType);
|
Assert.AreEqual(typeof(SettingsNewDatabasePage), selectedItem.PageType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TestEntryVm()
|
||||||
|
{
|
||||||
|
var database = new DatabaseServiceMock();
|
||||||
|
var entryVm = new EntryVm(new PwEntry(true, true), new GroupVm(), database)
|
||||||
|
{
|
||||||
|
Name = "Test",
|
||||||
|
UserName = "login",
|
||||||
|
Password = "password"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void TestGroupVm()
|
||||||
|
{
|
||||||
|
var database = new DatabaseServiceMock();
|
||||||
|
var entryVm = new GroupVm(new PwGroup(true, true), new GroupVm(), database)
|
||||||
|
{
|
||||||
|
Name = "Test"
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2018 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2018 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2018 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2018 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2018 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2018 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2018 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2018 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2018 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2018 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -69,7 +69,7 @@ namespace ModernKeePassLib.Cryptography.Cipher
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class ChaCha20Stream : Stream
|
internal sealed class ChaCha20Stream : Stream
|
||||||
{
|
{
|
||||||
private Stream m_sBase;
|
private Stream m_sBase;
|
||||||
private readonly bool m_bWriting;
|
private readonly bool m_bWriting;
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2018 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2018 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2018 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2018 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2018 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2018 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2018 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2018 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2018 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2018 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2018 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2018 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
KeePass Password Safe - The Open-Source Password Manager
|
KeePass Password Safe - The Open-Source Password Manager
|
||||||
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
|
Copyright (C) 2003-2018 Dominik Reichl <dominik.reichl@t-online.de>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -22,9 +22,13 @@ using System.Collections.Generic;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
|
#if ModernKeePassLib || KeePassUAP
|
||||||
using Org.BouncyCastle.Crypto;
|
using Org.BouncyCastle.Crypto;
|
||||||
using Org.BouncyCastle.Crypto.Engines;
|
using Org.BouncyCastle.Crypto.Engines;
|
||||||
using Org.BouncyCastle.Crypto.Parameters;
|
using Org.BouncyCastle.Crypto.Parameters;
|
||||||
|
#else
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
#endif
|
||||||
|
|
||||||
using ModernKeePassLib.Cryptography;
|
using ModernKeePassLib.Cryptography;
|
||||||
using ModernKeePassLib.Native;
|
using ModernKeePassLib.Native;
|
||||||
@@ -134,7 +138,7 @@ namespace ModernKeePassLib.Cryptography.KeyDerivation
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool TransformKeyManaged(byte[] pbNewKey32, byte[] pbKeySeed32,
|
internal static bool TransformKeyManaged(byte[] pbNewKey32, byte[] pbKeySeed32,
|
||||||
ulong uNumRounds)
|
ulong uNumRounds)
|
||||||
{
|
{
|
||||||
#if ModernKeePassLib || KeePassUAP
|
#if ModernKeePassLib || KeePassUAP
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user