mirror of
https://github.com/wismna/ModernKeePass.git
synced 2025-10-04 08:00:16 -04:00
Compare commits
23 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 |
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.Controls;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
using Microsoft.AppCenter;
|
||||
using Microsoft.AppCenter.Analytics;
|
||||
using Microsoft.AppCenter.Push;
|
||||
using ModernKeePass.Common;
|
||||
using ModernKeePass.Exceptions;
|
||||
using ModernKeePass.Services;
|
||||
@@ -20,20 +23,20 @@ namespace ModernKeePass
|
||||
/// </summary>
|
||||
sealed partial class App
|
||||
{
|
||||
public DatabaseService Database { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 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().
|
||||
/// </summary>
|
||||
public App()
|
||||
{
|
||||
AppCenter.Start("79d23520-a486-4f63-af81-8d90bf4e1bea", typeof(Analytics), typeof(Push));
|
||||
InitializeComponent();
|
||||
Suspending += OnSuspending;
|
||||
Resuming += OnResuming;
|
||||
UnhandledException += OnUnhandledException;
|
||||
Database = new DatabaseService();
|
||||
}
|
||||
|
||||
|
||||
#region Event Handlers
|
||||
|
||||
private void OnUnhandledException(object sender, UnhandledExceptionEventArgs unhandledExceptionEventArgs)
|
||||
@@ -46,9 +49,16 @@ namespace ModernKeePass
|
||||
? exception.InnerException
|
||||
: exception;
|
||||
|
||||
if (!(realException is SaveException)) return;
|
||||
unhandledExceptionEventArgs.Handled = true;
|
||||
MessageDialogHelper.SaveErrorDialog(realException as SaveException, Database);
|
||||
if (realException is SaveException)
|
||||
{
|
||||
unhandledExceptionEventArgs.Handled = true;
|
||||
MessageDialogHelper.SaveErrorDialog(realException as SaveException, DatabaseService.Instance);
|
||||
}
|
||||
else if (realException is DatabaseOpenedException)
|
||||
{
|
||||
unhandledExceptionEventArgs.Handled = true;
|
||||
MessageDialogHelper.SaveUnchangedDialog(realException as DatabaseOpenedException, DatabaseService.Instance);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -90,7 +100,10 @@ namespace ModernKeePass
|
||||
|
||||
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
|
||||
@@ -125,6 +138,31 @@ namespace ModernKeePass
|
||||
Window.Current.Activate();
|
||||
}
|
||||
|
||||
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>
|
||||
/// Invoked when Navigation to a certain page fails
|
||||
/// </summary>
|
||||
@@ -142,11 +180,21 @@ namespace ModernKeePass
|
||||
/// </summary>
|
||||
/// <param name="sender">The source of 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();
|
||||
UnhandledException -= OnUnhandledException;
|
||||
Database.Save();
|
||||
var database = DatabaseService.Instance;
|
||||
try
|
||||
{
|
||||
if (SettingsService.Instance.GetSetting("SaveSuspend", true)) database.Save();
|
||||
await database.Close(false);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
#if DEBUG
|
||||
ToastNotificationHelper.ShowErrorToast(exception);
|
||||
#endif
|
||||
}
|
||||
deferral.Complete();
|
||||
}
|
||||
|
||||
@@ -158,7 +206,7 @@ namespace ModernKeePass
|
||||
{
|
||||
base.OnFileActivated(args);
|
||||
var rootFrame = new Frame();
|
||||
Database.DatabaseFile = args.Files[0] as StorageFile;
|
||||
DatabaseService.Instance.DatabaseFile = args.Files[0] as StorageFile;
|
||||
rootFrame.Navigate(typeof(MainPage), args);
|
||||
Window.Current.Content = rootFrame;
|
||||
Window.Current.Activate();
|
||||
|
@@ -2,7 +2,6 @@
|
||||
using System.Collections.Generic;
|
||||
using Windows.Storage.Pickers;
|
||||
using Windows.UI.Popups;
|
||||
using Windows.UI.Xaml.Media.Animation;
|
||||
using ModernKeePass.Exceptions;
|
||||
using ModernKeePass.Interfaces;
|
||||
|
||||
@@ -10,19 +9,20 @@ namespace ModernKeePass.Common
|
||||
{
|
||||
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
|
||||
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
|
||||
messageDialog.Commands.Add(new UICommand(actionButtonText, action));
|
||||
messageDialog.Commands.Add(new UICommand(actionButtonText, actionCommand));
|
||||
|
||||
// Show the message dialog
|
||||
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 =>
|
||||
{
|
||||
@@ -35,6 +35,19 @@ namespace ModernKeePass.Common
|
||||
|
||||
var file = await savePicker.PickSaveFileAsync();
|
||||
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;
|
||||
// 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
|
||||
await messageDialog.ShowAsync();
|
||||
@@ -56,13 +69,13 @@ namespace ModernKeePass.Common
|
||||
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
|
||||
var messageDialog = new MessageDialog(message, title);
|
||||
|
||||
// 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
|
||||
messageDialog.DefaultCommandIndex = 1;
|
||||
|
@@ -45,5 +45,10 @@ namespace ModernKeePass.Common
|
||||
};
|
||||
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 ModernKeePassLib;
|
||||
using ModernKeePassLib.Cryptography.KeyDerivation;
|
||||
@@ -6,24 +7,29 @@ using ModernKeePassLib.Keys;
|
||||
|
||||
namespace ModernKeePass.Interfaces
|
||||
{
|
||||
public interface IDatabase
|
||||
public interface IDatabaseService
|
||||
{
|
||||
string Name { get; }
|
||||
bool RecycleBinEnabled { get; set; }
|
||||
int Status { get; set; }
|
||||
//int Status { get; set; }
|
||||
GroupVm RootGroup { get; set; }
|
||||
GroupVm RecycleBin { get; set; }
|
||||
StorageFile DatabaseFile { get; set; }
|
||||
CompositeKey CompositeKey { get; set; }
|
||||
PwUuid DataCipher { get; set; }
|
||||
PwCompressionAlgorithm CompressionAlgorithm { 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);
|
||||
void UpdateCompositeKey(CompositeKey key);
|
||||
Task Open(CompositeKey key, bool createNew = false);
|
||||
Task ReOpen();
|
||||
void Save();
|
||||
void Save(StorageFile file);
|
||||
void CreateRecycleBin();
|
||||
void CreateRecycleBin(string title);
|
||||
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>
|
||||
/// Delete from ViewModel
|
||||
/// </summary>
|
||||
void MarkForDelete();
|
||||
void MarkForDelete(string recycleBinTitle);
|
||||
}
|
||||
}
|
@@ -4,7 +4,7 @@ using Windows.Storage;
|
||||
|
||||
namespace ModernKeePass.Interfaces
|
||||
{
|
||||
public interface IRecent
|
||||
public interface IRecentService
|
||||
{
|
||||
int EntryCount { get; }
|
||||
Task<IStorageItem> GetFileAsync(string token);
|
@@ -1,6 +1,6 @@
|
||||
namespace ModernKeePass.Interfaces
|
||||
{
|
||||
public interface IResource
|
||||
public interface IResourceService
|
||||
{
|
||||
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>
|
||||
<ItemGroup>
|
||||
<Compile Include="Actions\ClipboardAction.cs" />
|
||||
<Compile Include="Actions\NavigateToUrlAction.cs" />
|
||||
<Compile Include="Actions\SetupFocusAction.cs" />
|
||||
<Compile Include="Aop\DatabaseChangedProxy.cs" />
|
||||
<Compile Include="App.xaml.cs">
|
||||
<DependentUpon>App.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Aop\DatabaseChanged.cs" />
|
||||
<Compile Include="Exceptions\DatabaseOpenedException.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\IResource.cs" />
|
||||
<Compile Include="ViewModels\DonateVm.cs" />
|
||||
<Compile Include="Interfaces\IResourceService.cs" />
|
||||
<Compile Include="Services\SingletonServiceBase.cs" />
|
||||
<Compile Include="TemplateSelectors\SelectableDataTemplateSelector.cs" />
|
||||
<Compile Include="ViewModels\Items\SettingsSaveVm.cs" />
|
||||
<Compile Include="Views\MainPageFrames\DonatePage.xaml.cs">
|
||||
<DependentUpon>DonatePage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Services\DatabaseService.cs" />
|
||||
<Compile Include="Interfaces\ISettings.cs" />
|
||||
<Compile Include="Interfaces\ISettingsService.cs" />
|
||||
<Compile Include="Common\MessageDialogHelper.cs" />
|
||||
<Compile Include="Common\NavigationHelper.cs" />
|
||||
<Compile Include="Common\NotifyPropertyChangedBase.cs" />
|
||||
@@ -139,7 +146,7 @@
|
||||
<Compile Include="Converters\NullToBooleanConverter.cs" />
|
||||
<Compile Include="Exceptions\SaveException.cs" />
|
||||
<Compile Include="Extensions\DispatcherTaskExtensions.cs" />
|
||||
<Compile Include="Interfaces\IDatabase.cs" />
|
||||
<Compile Include="Interfaces\IDatabaseService.cs" />
|
||||
<Compile Include="Interfaces\IHasSelectableObject.cs" />
|
||||
<Compile Include="Interfaces\ISelectableModel.cs" />
|
||||
<Compile Include="Views\BasePages\LayoutAwarePageBase.cs" />
|
||||
@@ -149,6 +156,9 @@
|
||||
<Compile Include="Views\SettingsPageFrames\SettingsNewDatabasePage.xaml.cs">
|
||||
<DependentUpon>SettingsNewDatabasePage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Views\SettingsPageFrames\SettingsSavePage.xaml.cs">
|
||||
<DependentUpon>SettingsSavePage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Views\SettingsPageFrames\SettingsSecurityPage.xaml.cs">
|
||||
<DependentUpon>SettingsSecurityPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
@@ -165,7 +175,6 @@
|
||||
<Compile Include="Converters\ColorToBrushConverter.cs" />
|
||||
<Compile Include="Converters\DoubleToSolidColorBrushConverter.cs" />
|
||||
<Compile Include="Converters\InverseBooleanToVisibilityConverter.cs" />
|
||||
<Compile Include="Converters\BooleanToFontStyleConverter.cs" />
|
||||
<Compile Include="Converters\PluralizationConverter.cs" />
|
||||
<Compile Include="Converters\ProgressBarLegalValuesConverter.cs" />
|
||||
<Compile Include="Converters\TextToWidthConverter.cs" />
|
||||
@@ -240,6 +249,10 @@
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</ApplicationDefinition>
|
||||
<Page Include="Views\SettingsPageFrames\SettingsSavePage.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Views\UserControls\CompositeKeyUserControl.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
@@ -335,12 +348,24 @@
|
||||
<HintPath>..\packages\Portable.BouncyCastle.1.8.1.3\lib\netstandard1.0\BouncyCastle.Crypto.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</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">
|
||||
<HintPath>..\packages\Microsoft.Toolkit.Uwp.Notifications.2.0.0\lib\dotnet\Microsoft.Toolkit.Uwp.Notifications.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<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>
|
||||
</Reference>
|
||||
<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-180.png" />
|
||||
<Content Include="Assets\Wide310x150Logo.scale-80.png" />
|
||||
<Content Include="Data\WindowsStoreProxy.xml">
|
||||
<SubType>Designer</SubType>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '12.0' ">
|
||||
<VisualStudioVersion>12.0</VisualStudioVersion>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<?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">
|
||||
<Identity Name="wismna.ModernKeePass" Publisher="CN=0719A91A-C322-4EE0-A257-E60733EECF06" Version="1.11.0.31" />
|
||||
<Identity Name="wismna.ModernKeePass" Publisher="CN=0719A91A-C322-4EE0-A257-E60733EECF06" Version="1.13.0.32" />
|
||||
<Properties>
|
||||
<DisplayName>ModernKeePass</DisplayName>
|
||||
<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
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.11.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.11.0.0")]
|
||||
[assembly: AssemblyVersion("1.13.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.13.0.0")]
|
||||
[assembly: ComVisible(false)]
|
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Storage;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using ModernKeePass.Exceptions;
|
||||
@@ -14,22 +15,14 @@ using ModernKeePassLib.Serialization;
|
||||
|
||||
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 ISettings _settings;
|
||||
private readonly IResource _resource;
|
||||
private readonly ISettingsService _settings;
|
||||
private StorageFile _realDatabaseFile;
|
||||
private StorageFile _databaseFile;
|
||||
private GroupVm _recycleBin;
|
||||
private CompositeKey _compositeKey;
|
||||
|
||||
public GroupVm RootGroup { get; set; }
|
||||
|
||||
@@ -39,11 +32,10 @@ namespace ModernKeePass.Services
|
||||
set
|
||||
{
|
||||
_recycleBin = value;
|
||||
_pwDatabase.RecycleBinUuid = _recycleBin.IdUuid;
|
||||
_pwDatabase.RecycleBinUuid = _recycleBin?.IdUuid;
|
||||
}
|
||||
}
|
||||
|
||||
public int Status { get; set; } = (int)DatabaseStatus.Closed;
|
||||
public string Name => DatabaseFile?.Name;
|
||||
|
||||
public bool RecycleBinEnabled
|
||||
@@ -57,11 +49,20 @@ namespace ModernKeePass.Services
|
||||
get { return _databaseFile; }
|
||||
set
|
||||
{
|
||||
if (IsOpen && HasChanged)
|
||||
{
|
||||
throw new DatabaseOpenedException();
|
||||
}
|
||||
_databaseFile = value;
|
||||
Status = (int)DatabaseStatus.Opening;
|
||||
}
|
||||
}
|
||||
|
||||
public CompositeKey CompositeKey
|
||||
{
|
||||
get { return _compositeKey; }
|
||||
set { _compositeKey = value; }
|
||||
}
|
||||
|
||||
public PwUuid DataCipher
|
||||
{
|
||||
get { return _pwDatabase.DataCipherUuid; }
|
||||
@@ -80,13 +81,20 @@ namespace ModernKeePass.Services
|
||||
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() : this(SettingsService.Instance)
|
||||
{
|
||||
}
|
||||
|
||||
public DatabaseService(ISettings settings)
|
||||
public DatabaseService(ISettingsService settings)
|
||||
{
|
||||
_settings = settings;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Open a KeePass database
|
||||
@@ -94,15 +102,17 @@ namespace ModernKeePass.Services
|
||||
/// <param name="key">The database composite key</param>
|
||||
/// <param name="createNew">True to create a new database before opening it</param>
|
||||
/// <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
|
||||
{
|
||||
if (key == null)
|
||||
{
|
||||
Status = (int)DatabaseStatus.NoCompositeKey;
|
||||
return;
|
||||
throw new ArgumentNullException(nameof(key));
|
||||
}
|
||||
|
||||
_compositeKey = key;
|
||||
var ioConnection = IOConnectionInfo.FromFile(DatabaseFile);
|
||||
if (createNew)
|
||||
{
|
||||
@@ -120,18 +130,50 @@ namespace ModernKeePass.Services
|
||||
}
|
||||
else _pwDatabase.Open(ioConnection, key, new NullStatusLogger());
|
||||
|
||||
if (!_pwDatabase.IsOpen) return;
|
||||
Status = (int)DatabaseStatus.Opened;
|
||||
//if (!_pwDatabase.IsOpen) return;
|
||||
|
||||
// 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);
|
||||
}
|
||||
catch (InvalidCompositeKeyException)
|
||||
catch (InvalidCompositeKeyException ex)
|
||||
{
|
||||
Status = (int)DatabaseStatus.CompositeKeyError;
|
||||
throw new ArgumentException(ex.Message, ex);
|
||||
}
|
||||
catch (Exception)
|
||||
}
|
||||
|
||||
public async Task ReOpen()
|
||||
{
|
||||
await Open(_compositeKey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Commit the changes to the currently opened database to file
|
||||
/// </summary>
|
||||
public void Save()
|
||||
{
|
||||
if (!IsOpen) return;
|
||||
try
|
||||
{
|
||||
Status = (int)DatabaseStatus.Error;
|
||||
throw;
|
||||
_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;
|
||||
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>
|
||||
/// Close the currently opened database
|
||||
/// </summary>
|
||||
public void Close()
|
||||
public async Task Close(bool releaseFile = true)
|
||||
{
|
||||
_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)
|
||||
@@ -188,18 +218,13 @@ namespace ModernKeePass.Services
|
||||
_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.IconSymbol = Symbol.Delete;
|
||||
}
|
||||
|
||||
public void UpdateCompositeKey(CompositeKey key)
|
||||
{
|
||||
_pwDatabase.MasterKey = key;
|
||||
}
|
||||
|
||||
|
||||
private void CreateSampleData()
|
||||
{
|
||||
_pwDatabase.RootGroup.AddGroup(new PwGroup(true, true, "Banking", PwIcon.Count), true);
|
||||
|
@@ -1,13 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.ApplicationModel;
|
||||
using Windows.ApplicationModel.Store;
|
||||
using ModernKeePass.Interfaces;
|
||||
|
||||
namespace ModernKeePass.Services
|
||||
{
|
||||
public class LicenseService : ILicenseService
|
||||
public class LicenseService : SingletonServiceBase<LicenseService>, ILicenseService
|
||||
{
|
||||
public enum PurchaseResult
|
||||
{
|
||||
@@ -27,34 +26,13 @@ namespace ModernKeePass.Services
|
||||
|
||||
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();
|
||||
#endif
|
||||
Products = listing.ProductListings;
|
||||
}
|
||||
|
||||
public async Task<int> Purchase(string addOn)
|
||||
{
|
||||
#if DEBUG
|
||||
var purchaseResults = await CurrentAppSimulator.RequestProductPurchaseAsync(addOn);
|
||||
#else
|
||||
var purchaseResults = await CurrentApp.RequestProductPurchaseAsync(addOn);
|
||||
#endif
|
||||
switch (purchaseResults.Status)
|
||||
{
|
||||
case ProductPurchaseStatus.Succeeded:
|
||||
@@ -79,11 +57,7 @@ namespace ModernKeePass.Services
|
||||
|
||||
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);
|
||||
#endif
|
||||
return (PurchaseResult) result;
|
||||
}
|
||||
|
||||
|
@@ -8,10 +8,10 @@ using ModernKeePass.ViewModels;
|
||||
|
||||
namespace ModernKeePass.Services
|
||||
{
|
||||
public class RecentService : IRecent
|
||||
public class RecentService : SingletonServiceBase<RecentService>, IRecentService
|
||||
{
|
||||
private readonly StorageItemMostRecentlyUsedList _mru = StorageApplicationPermissions.MostRecentlyUsedList;
|
||||
|
||||
|
||||
public int EntryCount => _mru.Entries.Count;
|
||||
|
||||
public ObservableCollection<IRecentItem> GetAllFiles(bool removeIfNonExistant = true)
|
||||
|
@@ -3,7 +3,7 @@ using ModernKeePass.Interfaces;
|
||||
|
||||
namespace ModernKeePass.Services
|
||||
{
|
||||
public class ResourcesService: IResource
|
||||
public class ResourcesService: IResourceService
|
||||
{
|
||||
private const string ResourceFileName = "CodeBehind";
|
||||
private readonly ResourceLoader _resourceLoader = ResourceLoader.GetForCurrentView();
|
||||
|
@@ -5,11 +5,11 @@ using ModernKeePass.Interfaces;
|
||||
|
||||
namespace ModernKeePass.Services
|
||||
{
|
||||
public class SettingsService : ISettings
|
||||
public class SettingsService : SingletonServiceBase<SettingsService>, ISettingsService
|
||||
{
|
||||
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
|
||||
{
|
||||
@@ -17,7 +17,7 @@ namespace ModernKeePass.Services
|
||||
}
|
||||
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">
|
||||
<value>Are you sure you want to delete this entry?</value>
|
||||
</data>
|
||||
<data name="EntryNew" xml:space="preserve">
|
||||
<value>< New entry ></value>
|
||||
</data>
|
||||
<data name="EntryRecycled" xml:space="preserve">
|
||||
<value>Entry moved to the Recycle bin</value>
|
||||
</data>
|
||||
@@ -222,9 +219,6 @@
|
||||
<data name="GroupDeletingConfirmation" xml:space="preserve">
|
||||
<value>Are you sure you want to delete the whole group and all its entries?</value>
|
||||
</data>
|
||||
<data name="GroupNew" xml:space="preserve">
|
||||
<value>< New group ></value>
|
||||
</data>
|
||||
<data name="GroupRecycled" xml:space="preserve">
|
||||
<value>Group moved to the Recycle bin</value>
|
||||
</data>
|
||||
@@ -270,4 +264,13 @@
|
||||
<data name="SettingsMenuItemSecurity" xml:space="preserve">
|
||||
<value>Security</value>
|
||||
</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>
|
@@ -171,11 +171,14 @@
|
||||
<data name="CompositeKeyPassword.PlaceholderText" xml:space="preserve">
|
||||
<value>Password</value>
|
||||
</data>
|
||||
<data name="CompositeKeyUserAccount.Text" xml:space="preserve">
|
||||
<value>Windows User Account</value>
|
||||
</data>
|
||||
<data name="DonateButton.Content" xml:space="preserve">
|
||||
<value>Donate</value>
|
||||
</data>
|
||||
<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 name="EntryExpirationDate.Content" xml:space="preserve">
|
||||
<value>Expiration date</value>
|
||||
@@ -183,6 +186,15 @@
|
||||
<data name="EntryExpirationTooltip.Content" xml:space="preserve">
|
||||
<value>Password has expired</value>
|
||||
</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">
|
||||
<value>User name or login</value>
|
||||
</data>
|
||||
@@ -202,10 +214,10 @@
|
||||
<value>Filter...</value>
|
||||
</data>
|
||||
<data name="GroupNewItemTextBox.Text" xml:space="preserve">
|
||||
<value>< New group ></value>
|
||||
<value>New group</value>
|
||||
</data>
|
||||
<data name="GroupNewItemTooltip.Content" xml:space="preserve">
|
||||
<value>< New group ></value>
|
||||
<value>New group</value>
|
||||
</data>
|
||||
<data name="GroupSearch.PlaceholderText" xml:space="preserve">
|
||||
<value>Search...</value>
|
||||
@@ -303,6 +315,12 @@
|
||||
<data name="SettingsDatabaseRecycleBin.OnContent" xml:space="preserve">
|
||||
<value>Enabled</value>
|
||||
</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">
|
||||
<value>Here, you can change some default options when creating a database.</value>
|
||||
</data>
|
||||
@@ -321,6 +339,18 @@
|
||||
<data name="SettingsNewDatabaseSample.OnContent" xml:space="preserve">
|
||||
<value>Yes</value>
|
||||
</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">
|
||||
<value>Here, you may change your database password, key file, or both. Just click on on</value>
|
||||
</data>
|
||||
|
@@ -204,10 +204,6 @@
|
||||
<data name="EntryDeletingConfirmation" xml:space="preserve">
|
||||
<value>Êtes-vous sûr de vouloir supprimer cette entrée ?</value>
|
||||
</data>
|
||||
<data name="EntryNew" xml:space="preserve">
|
||||
<value>< Nouvelle entrée ></value>
|
||||
<comment>Unused</comment>
|
||||
</data>
|
||||
<data name="EntryRecycled" xml:space="preserve">
|
||||
<value>Entrée placée dans la Corbeille</value>
|
||||
</data>
|
||||
@@ -223,9 +219,6 @@
|
||||
<data name="GroupDeletingConfirmation" xml:space="preserve">
|
||||
<value>Êtes-vous sûr de vouloir supprimer ce group et toutes ses entrées ?</value>
|
||||
</data>
|
||||
<data name="GroupNew" xml:space="preserve">
|
||||
<value>< Nouveau groupe ></value>
|
||||
</data>
|
||||
<data name="GroupRecycled" xml:space="preserve">
|
||||
<value>Groupe placé dans la Corbeille</value>
|
||||
</data>
|
||||
@@ -271,4 +264,13 @@
|
||||
<data name="SettingsMenuItemSecurity" xml:space="preserve">
|
||||
<value>Sécurité</value>
|
||||
</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>
|
@@ -142,7 +142,7 @@
|
||||
<value>Accueil</value>
|
||||
</data>
|
||||
<data name="AppBarRestore.Label" xml:space="preserve">
|
||||
<value>Restorer</value>
|
||||
<value>Restaurer</value>
|
||||
</data>
|
||||
<data name="AppBarSave.Label" xml:space="preserve">
|
||||
<value>Sauvegarder</value>
|
||||
@@ -171,6 +171,9 @@
|
||||
<data name="CompositeKeyPassword.PlaceholderText" xml:space="preserve">
|
||||
<value>Mot de passe</value>
|
||||
</data>
|
||||
<data name="CompositeKeyUserAccount.Text" xml:space="preserve">
|
||||
<value>Compte Utilisateur Windows</value>
|
||||
</data>
|
||||
<data name="DonateButton.Content" xml:space="preserve">
|
||||
<value>Donner</value>
|
||||
</data>
|
||||
@@ -183,6 +186,15 @@
|
||||
<data name="EntryExpirationTooltip.Content" xml:space="preserve">
|
||||
<value>Le mot de passe a expiré</value>
|
||||
</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">
|
||||
<value>Nom d'utilisateur ou login</value>
|
||||
</data>
|
||||
@@ -202,10 +214,10 @@
|
||||
<value>Filtrer...</value>
|
||||
</data>
|
||||
<data name="GroupNewItemTextBox.Text" xml:space="preserve">
|
||||
<value>< Nouveau groupe ></value>
|
||||
<value>Nouveau groupe</value>
|
||||
</data>
|
||||
<data name="GroupNewItemTooltip.Content" xml:space="preserve">
|
||||
<value>< Nouveau groupe ></value>
|
||||
<value>Nouveau groupe</value>
|
||||
</data>
|
||||
<data name="GroupSearch.PlaceholderText" xml:space="preserve">
|
||||
<value>Rechercher...</value>
|
||||
@@ -303,6 +315,12 @@
|
||||
<data name="SettingsDatabaseRecycleBin.OnContent" xml:space="preserve">
|
||||
<value>Activé</value>
|
||||
</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">
|
||||
<value>Ici, vous pouvez changer certains options lors de la création d'une nouvelle base de données</value>
|
||||
</data>
|
||||
@@ -321,6 +339,18 @@
|
||||
<data name="SettingsNewDatabaseSample.OnContent" xml:space="preserve">
|
||||
<value>Oui</value>
|
||||
</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">
|
||||
<value>Ici, vous pouvez changer le mot de passe maître, le fichier de clé, ou les deux. Cliquez simplement sur</value>
|
||||
</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.Threading.Tasks;
|
||||
using Windows.Storage;
|
||||
using Windows.UI.Xaml;
|
||||
using ModernKeePass.Common;
|
||||
using ModernKeePass.Interfaces;
|
||||
using ModernKeePass.Services;
|
||||
@@ -22,7 +21,7 @@ namespace ModernKeePass.ViewModels
|
||||
Success = 5
|
||||
}
|
||||
|
||||
public IDatabase Database { get; set; }
|
||||
public IDatabaseService Database { get; set; }
|
||||
|
||||
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
|
||||
{
|
||||
@@ -91,19 +100,21 @@ namespace ModernKeePass.ViewModels
|
||||
|
||||
public double PasswordComplexityIndicator => QualityEstimation.EstimatePasswordBits(Password?.ToCharArray());
|
||||
|
||||
|
||||
private bool _hasPassword;
|
||||
private bool _hasKeyFile;
|
||||
private bool _hasUserAccount;
|
||||
private bool _isOpening;
|
||||
private string _password = string.Empty;
|
||||
private string _status;
|
||||
private StatusTypes _statusType;
|
||||
private StorageFile _keyFile;
|
||||
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;
|
||||
_keyFileText = _resource.GetResourceValue("CompositeKeyDefaultKeyFile");
|
||||
@@ -112,42 +123,37 @@ namespace ModernKeePass.ViewModels
|
||||
|
||||
public async Task<bool> OpenDatabase(bool createNew)
|
||||
{
|
||||
var error = string.Empty;
|
||||
try
|
||||
{
|
||||
_isOpening = true;
|
||||
Database.Open(CreateCompositeKey(), createNew);
|
||||
await Database.Open(CreateCompositeKey(), createNew);
|
||||
await Task.Run(() => RootGroup = Database.RootGroup);
|
||||
return true;
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
var errorMessage = new StringBuilder(_resource.GetResourceValue("CompositeKeyErrorUserStart"));
|
||||
if (HasPassword) errorMessage.Append(_resource.GetResourceValue("CompositeKeyErrorUserPassword"));
|
||||
if (HasPassword && HasKeyFile) errorMessage.Append(_resource.GetResourceValue("CompositeKeyErrorUserOr"));
|
||||
if (HasKeyFile) errorMessage.Append(_resource.GetResourceValue("CompositeKeyErrorUserKeyFile"));
|
||||
if (HasUserAccount) errorMessage.Append(_resource.GetResourceValue("CompositeKeyErrorUserAccount"));
|
||||
UpdateStatus(errorMessage.ToString(), StatusTypes.Error);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
error = $"{_resource.GetResourceValue("CompositeKeyErrorOpen")}: {e.Message}";
|
||||
var error = $"{_resource.GetResourceValue("CompositeKeyErrorOpen")}: {e.Message}";
|
||||
UpdateStatus(error, StatusTypes.Error);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_isOpening = false;
|
||||
}
|
||||
switch ((DatabaseService.DatabaseStatus)Database.Status)
|
||||
{
|
||||
case DatabaseService.DatabaseStatus.Opened:
|
||||
await Task.Run(() => RootGroup = Database.RootGroup);
|
||||
return true;
|
||||
case DatabaseService.DatabaseStatus.CompositeKeyError:
|
||||
var errorMessage = new StringBuilder(_resource.GetResourceValue("CompositeKeyErrorUserStart"));
|
||||
if (HasPassword) errorMessage.Append(_resource.GetResourceValue("CompositeKeyErrorUserPassword"));
|
||||
if (HasPassword && HasKeyFile) errorMessage.Append(_resource.GetResourceValue("CompositeKeyErrorUserOr"));
|
||||
if (HasKeyFile) errorMessage.Append(_resource.GetResourceValue("CompositeKeyErrorUserKeyFile"));
|
||||
UpdateStatus(errorMessage.ToString(), StatusTypes.Error);
|
||||
break;
|
||||
case DatabaseService.DatabaseStatus.Error:
|
||||
UpdateStatus(error, StatusTypes.Error);
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void UpdateKey()
|
||||
{
|
||||
Database.UpdateCompositeKey(CreateCompositeKey());
|
||||
Database.CompositeKey = CreateCompositeKey();
|
||||
UpdateStatus(_resource.GetResourceValue("CompositeKeyUpdated"), StatusTypes.Success);
|
||||
}
|
||||
|
||||
@@ -169,6 +175,7 @@ namespace ModernKeePass.ViewModels
|
||||
var compositeKey = new CompositeKey();
|
||||
if (HasPassword) compositeKey.AddUserKey(new KcpPassword(Password));
|
||||
if (HasKeyFile && KeyFile != null) compositeKey.AddUserKey(new KcpKeyFile(IOConnectionInfo.FromFile(KeyFile)));
|
||||
if (HasUserAccount) compositeKey.AddUserKey(new KcpUserAccount());
|
||||
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,10 +1,11 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Text;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using ModernKeePass.Attributes;
|
||||
using ModernKeePass.Interfaces;
|
||||
using ModernKeePass.Mappings;
|
||||
using ModernKeePass.Services;
|
||||
using ModernKeePassLib;
|
||||
using ModernKeePassLib.Cryptography.PasswordGenerator;
|
||||
using ModernKeePassLib.Security;
|
||||
@@ -46,12 +47,7 @@ namespace ModernKeePass.ViewModels
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
/*var title = GetEntryValue(PwDefs.TitleField);
|
||||
return title == null ? _resource.GetResourceValue("EntryNew") : title;*/
|
||||
return GetEntryValue(PwDefs.TitleField);
|
||||
}
|
||||
get { return GetEntryValue(PwDefs.TitleField); }
|
||||
set { SetEntryValue(PwDefs.TitleField, value); }
|
||||
}
|
||||
|
||||
@@ -72,6 +68,7 @@ namespace ModernKeePass.ViewModels
|
||||
NotifyPropertyChanged("PasswordComplexityIndicator");
|
||||
}
|
||||
}
|
||||
|
||||
public string Url
|
||||
{
|
||||
get { return GetEntryValue(PwDefs.UrlField); }
|
||||
@@ -160,7 +157,7 @@ namespace ModernKeePass.ViewModels
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
private readonly PwEntry _pwEntry;
|
||||
private readonly IDatabase _database;
|
||||
private readonly IDatabaseService _database;
|
||||
private bool _isEditMode;
|
||||
private bool _isRevealPassword;
|
||||
private double _passwordLength = 25;
|
||||
@@ -173,9 +170,9 @@ namespace ModernKeePass.ViewModels
|
||||
|
||||
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;
|
||||
_pwEntry = entry;
|
||||
@@ -216,15 +213,16 @@ namespace ModernKeePass.ViewModels
|
||||
return _pwEntry?.Strings.GetSafe(key).ReadString();
|
||||
}
|
||||
|
||||
[DatabaseChanged]
|
||||
private void SetEntryValue(string key, string newValue)
|
||||
{
|
||||
_pwEntry?.Strings.Set(key, new ProtectedString(true, newValue));
|
||||
}
|
||||
|
||||
public void MarkForDelete()
|
||||
public void MarkForDelete(string recycleBinTitle)
|
||||
{
|
||||
if (_database.RecycleBinEnabled && _database.RecycleBin?.IdUuid == null)
|
||||
_database.CreateRecycleBin();
|
||||
_database.CreateRecycleBin(recycleBinTitle);
|
||||
Move(_database.RecycleBinEnabled && !ParentGroup.IsSelected ? _database.RecycleBin : null);
|
||||
}
|
||||
|
||||
|
@@ -3,11 +3,12 @@ using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using ModernKeePass.Attributes;
|
||||
using ModernKeePass.Common;
|
||||
using ModernKeePass.Interfaces;
|
||||
using ModernKeePass.Mappings;
|
||||
using ModernKeePass.Services;
|
||||
using ModernKeePassLib;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
@@ -54,6 +55,7 @@ namespace ModernKeePass.ViewModels
|
||||
public string Name
|
||||
{
|
||||
get { return _pwGroup == null ? string.Empty : _pwGroup.Name; }
|
||||
[DatabaseChanged]
|
||||
set { _pwGroup.Name = value; }
|
||||
}
|
||||
|
||||
@@ -61,7 +63,6 @@ namespace ModernKeePass.ViewModels
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_pwGroup == null) return Symbol.Add;
|
||||
var result = PwIconToSegoeMapping.GetSymbolFromIcon(_pwGroup.IconId);
|
||||
return result == Symbol.More ? Symbol.Folder : result;
|
||||
}
|
||||
@@ -92,20 +93,19 @@ namespace ModernKeePass.ViewModels
|
||||
}
|
||||
|
||||
private readonly PwGroup _pwGroup;
|
||||
private readonly IDatabase _database;
|
||||
private readonly IDatabaseService _database;
|
||||
private bool _isEditMode;
|
||||
private PwEntry _reorderedEntry;
|
||||
private ObservableCollection<EntryVm> _entries = new ObservableCollection<EntryVm>();
|
||||
private string _filter = string.Empty;
|
||||
private bool _isMenuClosed = true;
|
||||
|
||||
public GroupVm() {}
|
||||
|
||||
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;
|
||||
_database = database;
|
||||
@@ -115,9 +115,9 @@ namespace ModernKeePass.ViewModels
|
||||
Entries = new ObservableCollection<EntryVm>(pwGroup.Entries.Select(e => new EntryVm(e, this)));
|
||||
Entries.CollectionChanged += Entries_CollectionChanged;
|
||||
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)
|
||||
{
|
||||
switch (e.Action)
|
||||
@@ -133,7 +133,8 @@ namespace ModernKeePass.ViewModels
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[DatabaseChanged]
|
||||
public GroupVm AddNewGroup(string name = "")
|
||||
{
|
||||
var pwGroup = new PwGroup(true, true, name, PwIcon.Folder);
|
||||
@@ -152,10 +153,10 @@ namespace ModernKeePass.ViewModels
|
||||
return newEntry;
|
||||
}
|
||||
|
||||
public void MarkForDelete()
|
||||
public void MarkForDelete(string recycleBinTitle)
|
||||
{
|
||||
if (_database.RecycleBinEnabled && _database.RecycleBin?.IdUuid == null)
|
||||
_database.CreateRecycleBin();
|
||||
_database.CreateRecycleBin(recycleBinTitle);
|
||||
Move(_database.RecycleBinEnabled && !IsSelected ? _database.RecycleBin : null);
|
||||
}
|
||||
|
||||
@@ -164,6 +165,7 @@ namespace ModernKeePass.ViewModels
|
||||
Move(PreviousGroup);
|
||||
}
|
||||
|
||||
[DatabaseChanged]
|
||||
public void Move(GroupVm destination)
|
||||
{
|
||||
PreviousGroup = ParentGroup;
|
||||
@@ -191,6 +193,7 @@ namespace ModernKeePass.ViewModels
|
||||
_database.Save();
|
||||
}
|
||||
|
||||
[DatabaseChanged]
|
||||
public void SortEntries()
|
||||
{
|
||||
var comparer = new PwEntryComparer(PwDefs.TitleField, true, false);
|
||||
@@ -205,6 +208,7 @@ namespace ModernKeePass.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
[DatabaseChanged]
|
||||
public void SortGroups()
|
||||
{
|
||||
try
|
||||
|
@@ -1,6 +1,5 @@
|
||||
using Windows.Storage;
|
||||
using ModernKeePass.Common;
|
||||
using Windows.UI.Xaml;
|
||||
using ModernKeePass.Interfaces;
|
||||
using ModernKeePass.Services;
|
||||
|
||||
@@ -31,20 +30,20 @@ namespace ModernKeePass.ViewModels
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
@@ -2,9 +2,9 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using Windows.UI.Xaml;
|
||||
using ModernKeePass.Common;
|
||||
using ModernKeePass.Interfaces;
|
||||
using ModernKeePass.Services;
|
||||
using ModernKeePassLib;
|
||||
using ModernKeePassLib.Cryptography.Cipher;
|
||||
using ModernKeePassLib.Cryptography.KeyDerivation;
|
||||
@@ -14,7 +14,7 @@ namespace ModernKeePass.ViewModels
|
||||
// TODO: implement Kdf settings
|
||||
public class SettingsDatabaseVm: NotifyPropertyChangedBase, IHasSelectableObject
|
||||
{
|
||||
private readonly IDatabase _database;
|
||||
private readonly IDatabaseService _database;
|
||||
private GroupVm _selectedItem;
|
||||
|
||||
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 IEnumerable<string> Ciphers
|
||||
@@ -73,7 +82,7 @@ namespace ModernKeePass.ViewModels
|
||||
get { return Groups.FirstOrDefault(g => g.IsSelected); }
|
||||
set
|
||||
{
|
||||
if (_selectedItem == value) return;
|
||||
if (_selectedItem == value || IsNewRecycleBin) return;
|
||||
if (_selectedItem != null)
|
||||
{
|
||||
_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;
|
||||
Groups = _database?.RootGroup.Groups;
|
||||
|
@@ -6,12 +6,12 @@ namespace ModernKeePass.ViewModels
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
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.Linq;
|
||||
using Windows.ApplicationModel;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using ModernKeePass.Common;
|
||||
using ModernKeePass.Interfaces;
|
||||
@@ -46,12 +45,12 @@ namespace ModernKeePass.ViewModels
|
||||
public MainVm() {}
|
||||
|
||||
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>
|
||||
{
|
||||
@@ -62,7 +61,7 @@ namespace ModernKeePass.ViewModels
|
||||
Destination = destinationFrame,
|
||||
Parameter = referenceFrame,
|
||||
SymbolIcon = Symbol.Page2,
|
||||
IsSelected = database != null && database.Status == (int) DatabaseService.DatabaseStatus.Opening
|
||||
IsSelected = database != null && database.IsFileOpen && !database.IsOpen
|
||||
},
|
||||
new MainMenuItemVm
|
||||
{
|
||||
@@ -90,7 +89,7 @@ namespace ModernKeePass.ViewModels
|
||||
Parameter = referenceFrame,
|
||||
SymbolIcon = Symbol.Copy,
|
||||
IsSelected =
|
||||
(database == null || database.Status == (int) DatabaseService.DatabaseStatus.Closed) &&
|
||||
(database == null || database.IsClosed) &&
|
||||
recent.EntryCount > 0,
|
||||
IsEnabled = recent.EntryCount > 0
|
||||
},
|
||||
@@ -120,7 +119,7 @@ namespace ModernKeePass.ViewModels
|
||||
SelectedItem = mainMenuItems.FirstOrDefault(m => m.IsSelected);
|
||||
|
||||
// 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
|
||||
{
|
||||
Title = database.Name,
|
||||
|
@@ -1,5 +1,4 @@
|
||||
using Windows.Storage;
|
||||
using Windows.UI.Xaml;
|
||||
using ModernKeePass.Common;
|
||||
using ModernKeePass.Interfaces;
|
||||
using ModernKeePass.Services;
|
||||
@@ -8,27 +7,27 @@ namespace ModernKeePass.ViewModels
|
||||
{
|
||||
public class OpenVm: NotifyPropertyChangedBase
|
||||
{
|
||||
public bool ShowPasswordBox => _database?.Status == (int) DatabaseService.DatabaseStatus.Opening;
|
||||
public bool ShowPasswordBox => _database.IsFileOpen;
|
||||
|
||||
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;
|
||||
if (database == null || database.Status != (int) DatabaseService.DatabaseStatus.Opening) return;
|
||||
if (database == null || !database.IsFileOpen) return;
|
||||
OpenFile(database.DatabaseFile);
|
||||
}
|
||||
|
||||
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;
|
||||
OnPropertyChanged("Name");
|
||||
@@ -36,7 +35,7 @@ namespace ModernKeePass.ViewModels
|
||||
AddToRecentList(file, recent);
|
||||
}
|
||||
|
||||
private void AddToRecentList(StorageFile file, IRecent recent)
|
||||
private void AddToRecentList(StorageFile file, IRecentService recent)
|
||||
{
|
||||
recent.Add(file, file.DisplayName);
|
||||
}
|
||||
|
@@ -7,7 +7,7 @@ namespace ModernKeePass.ViewModels
|
||||
{
|
||||
public class RecentVm : NotifyPropertyChangedBase, IHasSelectableObject
|
||||
{
|
||||
private readonly IRecent _recent;
|
||||
private readonly IRecentService _recent;
|
||||
private ISelectableModel _selectedItem;
|
||||
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;
|
||||
RecentItems = _recent.GetAllFiles();
|
||||
|
@@ -1,23 +1,25 @@
|
||||
using Windows.Storage;
|
||||
using Windows.UI.Xaml;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Storage;
|
||||
using ModernKeePass.Interfaces;
|
||||
using ModernKeePass.Services;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
{
|
||||
public class SaveVm
|
||||
{
|
||||
private readonly IDatabase _database;
|
||||
public SaveVm() : this((Application.Current as App)?.Database) { }
|
||||
private readonly IDatabaseService _database;
|
||||
public SaveVm() : this(DatabaseService.Instance) { }
|
||||
|
||||
public SaveVm(IDatabase database)
|
||||
public SaveVm(IDatabaseService database)
|
||||
{
|
||||
_database = database;
|
||||
}
|
||||
|
||||
public void Save(bool close = true)
|
||||
public async Task Save(bool close = true)
|
||||
{
|
||||
_database.Save();
|
||||
if (close) _database.Close();
|
||||
if (close)
|
||||
await _database.Close();
|
||||
}
|
||||
|
||||
public void Save(StorageFile file)
|
||||
|
@@ -1,6 +1,5 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using ModernKeePass.Common;
|
||||
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>
|
||||
{
|
||||
@@ -56,12 +55,19 @@ namespace ModernKeePass.ViewModels
|
||||
IsSelected = true
|
||||
},
|
||||
new ListMenuItemVm
|
||||
{
|
||||
Title = resource.GetResourceValue("SettingsMenuItemSave"),
|
||||
Group = resource.GetResourceValue("SettingsMenuGroupApplication"),
|
||||
SymbolIcon = Symbol.Save,
|
||||
PageType = typeof(SettingsSavePage)
|
||||
},
|
||||
new ListMenuItemVm
|
||||
{
|
||||
Title = resource.GetResourceValue("SettingsMenuItemGeneral"),
|
||||
Group = resource.GetResourceValue("SettingsMenuGroupDatabase"),
|
||||
SymbolIcon = Symbol.Setting,
|
||||
PageType = typeof(SettingsDatabasePage),
|
||||
IsEnabled = database?.Status == 2
|
||||
IsEnabled = database.IsOpen
|
||||
},
|
||||
new ListMenuItemVm
|
||||
{
|
||||
@@ -69,7 +75,7 @@ namespace ModernKeePass.ViewModels
|
||||
Group = resource.GetResourceValue("SettingsMenuGroupDatabase"),
|
||||
SymbolIcon = Symbol.Permissions,
|
||||
PageType = typeof(SettingsSecurityPage),
|
||||
IsEnabled = database?.Status == 2
|
||||
IsEnabled = database.IsOpen
|
||||
}
|
||||
};
|
||||
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}}" />
|
||||
<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"/>
|
||||
<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" />
|
||||
<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}" />
|
||||
|
@@ -81,9 +81,9 @@ namespace ModernKeePass.Views
|
||||
resource.GetResourceValue("EntityDeleteCancelButton"), a =>
|
||||
{
|
||||
ToastNotificationHelper.ShowMovedToast(Model, resource.GetResourceValue("EntityDeleting"), text);
|
||||
Model.MarkForDelete();
|
||||
Model.MarkForDelete(resource.GetResourceValue("RecycleBinTitle"));
|
||||
if (Frame.CanGoBack) Frame.GoBack();
|
||||
});
|
||||
}, null);
|
||||
}
|
||||
|
||||
private void RestoreButton_Click(object sender, RoutedEventArgs e)
|
||||
@@ -92,20 +92,7 @@ namespace ModernKeePass.Views
|
||||
ToastNotificationHelper.ShowMovedToast(Model, resource.GetResourceValue("EntityRestoredTitle"), resource.GetResourceValue("EntryRestored"));
|
||||
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)
|
||||
{
|
||||
VisualStateManager.GoToState(this, e.NewSize.Width < 700 ? "Small" : "Large", true);
|
||||
|
@@ -8,7 +8,6 @@
|
||||
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
|
||||
xmlns:core="using:Microsoft.Xaml.Interactions.Core"
|
||||
xmlns:actions="using:ModernKeePass.Actions"
|
||||
xmlns:controls="using:ModernKeePass.Controls"
|
||||
xmlns:templateSelectors="using:ModernKeePass.TemplateSelectors"
|
||||
x:Name="PageRoot"
|
||||
x:Class="ModernKeePass.Views.GroupDetailPage"
|
||||
@@ -16,7 +15,6 @@
|
||||
SizeChanged="GroupDetailPage_OnSizeChanged">
|
||||
<Page.Resources>
|
||||
<converters:ColorToBrushConverter x:Key="ColorToBrushConverter"/>
|
||||
<converters:BooleanToFontStyleConverter x:Key="BooleanToFontStyleConverter"/>
|
||||
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
|
||||
<converters:InverseBooleanToVisibilityConverter x:Key="InverseBooleanToVisibilityConverter"/>
|
||||
<converters:NullToBooleanConverter x:Key="NullToBooleanConverter"/>
|
||||
@@ -84,7 +82,7 @@
|
||||
</core:EventTriggerBehavior>
|
||||
</interactivity:Interaction.Behaviors>
|
||||
</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>
|
||||
</Page.BottomAppBar>
|
||||
<Grid>
|
||||
@@ -127,27 +125,30 @@
|
||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
|
||||
Foreground="{ThemeResource DefaultTextForegroundThemeBrush}">
|
||||
<ListView.Resources>
|
||||
<DataTemplate x:Name="GroupOtherItem">
|
||||
<DataTemplate x:Name="IsRecycleBin">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<SymbolIcon Symbol="{Binding IconSymbol}" Margin="8,0,0,0">
|
||||
<ToolTipService.ToolTip>
|
||||
<ToolTip Content="{Binding Name}" />
|
||||
</ToolTipService.ToolTip>
|
||||
</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>
|
||||
</DataTemplate>
|
||||
<DataTemplate x:Name="GroupFirstItem">
|
||||
<DataTemplate x:Name="IsNotRecycleBin">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<SymbolIcon Symbol="{Binding IconSymbol}" Margin="8,0,0,0">
|
||||
<ToolTipService.ToolTip>
|
||||
<ToolTip x:Uid="GroupNewItemTooltip" />
|
||||
<ToolTip Content="{Binding Name}" />
|
||||
</ToolTipService.ToolTip>
|
||||
</SymbolIcon>
|
||||
<TextBlock x:Name="GroupTextBlock" x:Uid="GroupNewItemTextBox" FontWeight="SemiBold" TextWrapping="NoWrap" VerticalAlignment="Center" Margin="30,0,20,0" />
|
||||
</SymbolIcon>
|
||||
<TextBlock Text="{Binding Name}" x:Name="GroupTextBlock" TextWrapping="NoWrap" VerticalAlignment="Center" Margin="30,0,20,0" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ListView.Resources>
|
||||
<ListView.ItemTemplateSelector>
|
||||
<templateSelectors:SelectableDataTemplateSelector FalseItem="{StaticResource IsNotRecycleBin}" TrueItem="{StaticResource IsRecycleBin}" />
|
||||
</ListView.ItemTemplateSelector>
|
||||
<ListView.ItemsSource>
|
||||
<Binding Source="{StaticResource GroupsViewSource}"/>
|
||||
</ListView.ItemsSource>
|
||||
@@ -161,23 +162,35 @@
|
||||
</ListView.ItemContainerStyle>
|
||||
<ListView.HeaderTemplate>
|
||||
<DataTemplate>
|
||||
<ToggleButton Style="{StaticResource HamburgerToggleButton}">
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<core:EventTriggerBehavior EventName="Checked">
|
||||
<core:ChangePropertyAction PropertyName="Width" Value="Auto" TargetObject="{Binding ElementName=LeftListViewColumn}"/>
|
||||
</core:EventTriggerBehavior>
|
||||
<core:EventTriggerBehavior EventName="Unchecked">
|
||||
<core:ChangePropertyAction PropertyName="Width" Value="50" TargetObject="{Binding ElementName=LeftListViewColumn}"/>
|
||||
</core:EventTriggerBehavior>
|
||||
</interactivity:Interaction.Behaviors>
|
||||
</ToggleButton>
|
||||
<ToggleButton Style="{StaticResource HamburgerToggleButton}">
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<core:EventTriggerBehavior EventName="Checked">
|
||||
<core:ChangePropertyAction PropertyName="Width" Value="Auto" TargetObject="{Binding ElementName=LeftListViewColumn}"/>
|
||||
</core:EventTriggerBehavior>
|
||||
<core:EventTriggerBehavior EventName="Unchecked">
|
||||
<core:ChangePropertyAction PropertyName="Width" Value="50" TargetObject="{Binding ElementName=LeftListViewColumn}"/>
|
||||
</core:EventTriggerBehavior>
|
||||
</interactivity:Interaction.Behaviors>
|
||||
</ToggleButton>
|
||||
</DataTemplate>
|
||||
</ListView.HeaderTemplate>
|
||||
<ListView.ItemTemplateSelector>
|
||||
<templateSelectors:FirstItemDataTemplateSelector
|
||||
FirstItem="{StaticResource GroupFirstItem}"
|
||||
OtherItem="{StaticResource GroupOtherItem}" />
|
||||
</ListView.ItemTemplateSelector>
|
||||
<ListView.FooterTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Vertical" Visibility="{Binding IsSelected, Converter={StaticResource InverseBooleanToVisibilityConverter}}">
|
||||
<Border BorderBrush="White" BorderThickness="0,0,0,1" />
|
||||
<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>
|
||||
<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">
|
||||
@@ -212,6 +225,7 @@
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<SymbolIcon Grid.Column="0" Symbol="{Binding IconSymbol}" Width="100" Height="100" RenderTransformOrigin="0.5,0.5" >
|
||||
<SymbolIcon.RenderTransform>
|
||||
@@ -224,6 +238,34 @@
|
||||
<TextBlock Text="{Binding UserName}" Style="{StaticResource BodyTextBlockStyle}" MaxHeight="60" />
|
||||
<TextBlock Text="{Binding Url}" Style="{StaticResource BodyTextBlockStyle}" MaxHeight="60" />
|
||||
</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>
|
||||
</DataTemplate>
|
||||
</GridView.ItemTemplate>
|
||||
@@ -341,13 +383,18 @@
|
||||
<SymbolIcon Symbol="Find" />
|
||||
<Button.Flyout>
|
||||
<Flyout>
|
||||
<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" Background="{ThemeResource TextBoxDisabledBackgroundThemeBrush}" BorderThickness="0" FontSize="18" SuggestionsRequested="SearchBox_OnSuggestionsRequested" SearchHistoryEnabled="False" ResultSuggestionChosen="SearchBox_OnResultSuggestionChosen" VerticalContentAlignment="Center" />
|
||||
<SearchBox x:Uid="GroupSearch" Width="350" Padding="12" Background="{ThemeResource TextBoxDisabledBackgroundThemeBrush}" BorderThickness="0" FontSize="18" SuggestionsRequested="SearchBox_OnSuggestionsRequested" SearchHistoryEnabled="False" ResultSuggestionChosen="SearchBox_OnResultSuggestionChosen" />
|
||||
</Flyout>
|
||||
</Button.Flyout>
|
||||
</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" />-->
|
||||
<SearchBox Grid.Column="2" x:Uid="GroupSearch" x:Name="SearchBox" Width="350" Background="{ThemeResource TextBoxDisabledBackgroundThemeBrush}" BorderThickness="0" FontSize="18" SuggestionsRequested="SearchBox_OnSuggestionsRequested" SearchHistoryEnabled="False" ResultSuggestionChosen="SearchBox_OnResultSuggestionChosen" VerticalContentAlignment="Center" />
|
||||
<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>
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="DragDropGroup">
|
||||
|
@@ -84,9 +84,6 @@ namespace ModernKeePass.Views
|
||||
{
|
||||
case -1:
|
||||
return;
|
||||
case 0:
|
||||
group = Model.AddNewGroup();
|
||||
break;
|
||||
default:
|
||||
group = LeftListView.SelectedItem as GroupVm;
|
||||
break;
|
||||
@@ -120,9 +117,9 @@ namespace ModernKeePass.Views
|
||||
resource.GetResourceValue("EntityDeleteCancelButton"), a =>
|
||||
{
|
||||
ToastNotificationHelper.ShowMovedToast(Model, resource.GetResourceValue("EntityDeleting"), text);
|
||||
Model.MarkForDelete();
|
||||
Model.MarkForDelete(resource.GetResourceValue("RecycleBinTitle"));
|
||||
if (Frame.CanGoBack) Frame.GoBack();
|
||||
});
|
||||
}, null);
|
||||
}
|
||||
|
||||
private void RestoreButton_Click(object sender, RoutedEventArgs e)
|
||||
@@ -145,6 +142,10 @@ namespace ModernKeePass.Views
|
||||
{
|
||||
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)
|
||||
{
|
||||
@@ -168,7 +169,6 @@ namespace ModernKeePass.Views
|
||||
Frame.Navigate(typeof(EntryDetailPage), entry);
|
||||
}
|
||||
|
||||
|
||||
private void GroupDetailPage_OnSizeChanged(object sender, SizeChangedEventArgs e)
|
||||
{
|
||||
VisualStateManager.GoToState(this, e.NewSize.Width < 700 ? "Small" : "Large", true);
|
||||
|
@@ -4,27 +4,6 @@
|
||||
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"
|
||||
xmlns:converters="using:ModernKeePass.Converters"
|
||||
mc:Ignorable="d">
|
||||
<Page.DataContext>
|
||||
<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>
|
||||
<WebView Source="https://PayPal.Me/wismna"></WebView>
|
||||
</Page>
|
||||
|
@@ -1,12 +1,4 @@
|
||||
using System;
|
||||
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
|
||||
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
|
||||
|
||||
namespace ModernKeePass.Views
|
||||
{
|
||||
@@ -15,57 +7,9 @@ namespace ModernKeePass.Views
|
||||
/// </summary>
|
||||
public sealed partial class DonatePage
|
||||
{
|
||||
public DonateVm Model => DataContext as DonateVm;
|
||||
|
||||
public DonatePage()
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
private void SaveButton_OnClick(object sender, RoutedEventArgs e)
|
||||
private async void SaveButton_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Model.Save();
|
||||
_mainFrame.Navigate(typeof(Views.MainPage));
|
||||
await Model.Save();
|
||||
_mainFrame.Navigate(typeof(MainPage));
|
||||
}
|
||||
|
||||
private async void SaveAsButton_OnClick(object sender, RoutedEventArgs e)
|
||||
@@ -47,7 +47,7 @@ namespace ModernKeePass.Views
|
||||
if (file == null) return;
|
||||
Model.Save(file);
|
||||
|
||||
_mainFrame.Navigate(typeof(Views.MainPage));
|
||||
_mainFrame.Navigate(typeof(MainPage));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -5,35 +5,27 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:viewModels="using:ModernKeePass.ViewModels"
|
||||
xmlns:templateSelectors="using:ModernKeePass.TemplateSelectors"
|
||||
xmlns:converters="using:ModernKeePass.Converters"
|
||||
mc:Ignorable="d">
|
||||
<Page.Resources>
|
||||
<CollectionViewSource x:Name="RecycleBinGroups" Source="{Binding Groups}" />
|
||||
<CollectionViewSource x:Name="Ciphers" Source="{Binding Ciphers}" />
|
||||
<CollectionViewSource x:Name="Compressions" Source="{Binding Compressions}" />
|
||||
<CollectionViewSource x:Name="KeyDerivations" Source="{Binding KeyDerivations}" />
|
||||
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
|
||||
<converters:NullToBooleanConverter x:Key="NullToBooleanConverter"/>
|
||||
</Page.Resources>
|
||||
<Page.DataContext>
|
||||
<viewModels:SettingsDatabaseVm />
|
||||
</Page.DataContext>
|
||||
|
||||
|
||||
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||
<ToggleSwitch x:Uid="SettingsDatabaseRecycleBin" IsOn="{Binding HasRecycleBin, Mode=TwoWay}" />
|
||||
<ComboBox ItemsSource="{Binding Source={StaticResource RecycleBinGroups}}" SelectedItem="{Binding SelectedItem, Mode=TwoWay}" IsEnabled="{Binding HasRecycleBin}">
|
||||
<ComboBox.Resources>
|
||||
<DataTemplate x:Name="GroupFirstItem">
|
||||
<TextBlock x:Uid="GroupNewItemTextBox" />
|
||||
</DataTemplate>
|
||||
<DataTemplate x:Name="GroupOtherItem">
|
||||
<TextBlock Text="{Binding}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.Resources>
|
||||
<ComboBox.ItemTemplateSelector>
|
||||
<templateSelectors:FirstItemDataTemplateSelector
|
||||
FirstItem="{StaticResource GroupFirstItem}"
|
||||
OtherItem="{StaticResource GroupOtherItem}" />
|
||||
</ComboBox.ItemTemplateSelector>
|
||||
</ComboBox>
|
||||
<StackPanel Visibility="{Binding HasRecycleBin, Converter={StaticResource BooleanToVisibilityConverter}}">
|
||||
<RadioButton x:Uid="SettingsDatabaseRecycleBinCreate" GroupName="Recycle" IsChecked="{Binding IsNewRecycleBin, Mode=TwoWay}" />
|
||||
<RadioButton x:Name="RadioButton" x:Uid="SettingsDatabaseRecycleBinExisting" GroupName="Recycle" IsChecked="{Binding SelectedItem, Converter={StaticResource NullToBooleanConverter}}" />
|
||||
<ComboBox ItemsSource="{Binding Source={StaticResource RecycleBinGroups}}" SelectedItem="{Binding SelectedItem, Mode=TwoWay}" IsEnabled="{Binding IsChecked, ElementName=RadioButton}" />
|
||||
</StackPanel>
|
||||
<TextBlock x:Uid="SettingsDatabaseEncryption" Style="{StaticResource TextBlockSettingsHeaderStyle}" Margin="5,20,0,10" />
|
||||
<ComboBox ItemsSource="{Binding Source={StaticResource Ciphers}}" SelectedIndex="{Binding CipherIndex, Mode=TwoWay}" />
|
||||
<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"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:ModernKeePass.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:userControls="using:ModernKeePass.Views.UserControls"
|
||||
|
@@ -11,7 +11,6 @@
|
||||
xmlns:viewModels="using:ModernKeePass.ViewModels"
|
||||
mc:Ignorable="d" >
|
||||
<UserControl.Resources>
|
||||
<SolidColorBrush x:Key="ErrorColorBrush" Color="Red"/>
|
||||
<converters:ProgressBarLegalValuesConverter x:Key="ProgressBarLegalValuesConverter"/>
|
||||
<converters:DoubleToSolidColorBrushConverter x:Key="DoubleToForegroungBrushConverter"/>
|
||||
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
|
||||
@@ -55,7 +54,7 @@
|
||||
</ToolTipService.ToolTip>
|
||||
</SymbolIcon>
|
||||
</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}" />
|
||||
<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>
|
||||
</UserControl>
|
||||
|
@@ -90,7 +90,12 @@ namespace ModernKeePass.Views.UserControls
|
||||
|
||||
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)
|
||||
|
@@ -1,2 +1,4 @@
|
||||
Error when opening file from Explorer corrected
|
||||
Filter entries reverted to search entries because of regressions
|
||||
Application now correctly resumes from suspend
|
||||
Code enhancements
|
||||
Return of the Donate page, with Paypal
|
||||
KeePassLib version bump to 2.38
|
@@ -1,6 +1,6 @@
|
||||
En avez-vous assez d'essayer de retenir des quantités de mots de passe ? Etes-vous soucieux que le fait d'utiliser le même mot de passe partout vous rend vulnérable ?
|
||||
ModernKeePass est un gestionnaire de mots de passe gratuit, libre, facile à utiliser mais néanmoins s<EFBFBD>r, basé sur la technologie certifiée et répandue KeePass 2.x et compatible avec celui-ci.
|
||||
Vous pouvez stocker ou générer vos mots de passe dans une base de données chiffrée, qui peut être placée n'importe o<EFBFBD> (ordinateur personnel/tablette, cloud, clé USB...)
|
||||
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 a utiliser mais neanmoins sur, base sur la technologie certifiee et repandue KeePass 2.x et compatible avec celui-ci.
|
||||
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écurité informatique soit très importante, cette application essaie de rester simple à utiliser et à 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.
|
@@ -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,2 +1,4 @@
|
||||
Correction d'un bug lors de l'ouverture d'un fichier par Explorer
|
||||
Rétablissement de la recherche d'entrées à la place du filtre à cause de régressions multiples
|
||||
L'application recupere correctement d'une suspension
|
||||
Ameliorations de code
|
||||
Retour de la page de donation, avec Paypal
|
||||
Version de la KeePassLib montee a 2.38
|
@@ -1,10 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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.NETCore.Platforms" version="2.0.1" 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="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="Portable.BouncyCastle" version="1.8.1.3" targetFramework="win81" />
|
||||
<package id="Splat" version="2.0.0" targetFramework="win81" />
|
||||
|
@@ -16,20 +16,20 @@ namespace ModernKeePassApp.Test
|
||||
[TestMethod]
|
||||
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();
|
||||
Assert.AreEqual((int)DatabaseService.DatabaseStatus.Opening, _database.Status);
|
||||
Assert.IsTrue(_database.IsFileOpen);
|
||||
OpenOrCreateDatabase(true);
|
||||
_database.Close();
|
||||
Assert.AreEqual((int)DatabaseService.DatabaseStatus.Closed, _database.Status);
|
||||
_database.Close().GetAwaiter().GetResult();
|
||||
Assert.IsTrue(_database.IsClosed);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestOpen()
|
||||
{
|
||||
Assert.AreEqual((int)DatabaseService.DatabaseStatus.Closed, _database.Status);
|
||||
_database.DatabaseFile = Package.Current.InstalledLocation.GetFileAsync(@"Databases\TestDatabase.kdbx").GetAwaiter().GetResult();
|
||||
Assert.AreEqual((int)DatabaseService.DatabaseStatus.Opening, _database.Status);
|
||||
Assert.IsTrue(_database.IsClosed);
|
||||
_database.DatabaseFile = Package.Current.InstalledLocation.GetFileAsync(@"Data\TestDatabase.kdbx").GetAwaiter().GetResult();
|
||||
Assert.IsTrue(_database.IsFileOpen);
|
||||
OpenOrCreateDatabase(false);
|
||||
}
|
||||
|
||||
@@ -38,23 +38,23 @@ namespace ModernKeePassApp.Test
|
||||
{
|
||||
TestOpen();
|
||||
_database.Save(ApplicationData.Current.TemporaryFolder.CreateFileAsync("SaveDatabase.kdbx").GetAwaiter().GetResult());
|
||||
Assert.AreEqual((int)DatabaseService.DatabaseStatus.Opened, _database.Status);
|
||||
_database.Close();
|
||||
Assert.AreEqual((int)DatabaseService.DatabaseStatus.Closed, _database.Status);
|
||||
Assert.IsTrue(_database.IsOpen);
|
||||
_database.Close().GetAwaiter().GetResult();
|
||||
Assert.IsTrue(_database.IsClosed);
|
||||
TestOpen();
|
||||
}
|
||||
|
||||
private void OpenOrCreateDatabase(bool createNew)
|
||||
{
|
||||
_database.Open(null, createNew);
|
||||
Assert.AreEqual((int)DatabaseService.DatabaseStatus.NoCompositeKey, _database.Status);
|
||||
Assert.ThrowsException<ArgumentNullException>(
|
||||
() => _database.Open(null, createNew).GetAwaiter().GetResult());
|
||||
var compositeKey = new CompositeKeyVm(_database, new ResourceServiceMock())
|
||||
{
|
||||
HasPassword = true,
|
||||
Password = "test"
|
||||
};
|
||||
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.Threading.Tasks;
|
||||
using ModernKeePass.Interfaces;
|
||||
using ModernKeePass.ViewModels;
|
||||
using ModernKeePassLib;
|
||||
@@ -8,16 +9,34 @@ using Windows.Storage;
|
||||
|
||||
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 StorageFile DatabaseFile { get; set; }
|
||||
|
||||
public CompositeKey CompositeKey
|
||||
{
|
||||
get { return _compositeKey; }
|
||||
set { _compositeKey = value; }
|
||||
}
|
||||
|
||||
public PwUuid DataCipher { 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 GroupVm RecycleBin { get; set; }
|
||||
@@ -25,42 +44,49 @@ namespace ModernKeePassApp.Test.Mock
|
||||
public bool RecycleBinEnabled { get; set; }
|
||||
|
||||
public GroupVm RootGroup { get; set; }
|
||||
|
||||
public int Status { get; set; }
|
||||
|
||||
|
||||
public void AddDeletedItem(PwUuid id)
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
// Do Nothing
|
||||
}
|
||||
|
||||
public void Save(StorageFile file)
|
||||
{
|
||||
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
|
||||
{
|
||||
class RecentServiceMock : IRecent
|
||||
class RecentServiceMock : IRecentService
|
||||
{
|
||||
public int EntryCount => 0;
|
||||
|
||||
|
@@ -1,9 +1,8 @@
|
||||
using System;
|
||||
using ModernKeePass.Interfaces;
|
||||
using ModernKeePass.Interfaces;
|
||||
|
||||
namespace ModernKeePassApp.Test.Mock
|
||||
{
|
||||
class ResourceServiceMock : IResource
|
||||
class ResourceServiceMock : IResourceService
|
||||
{
|
||||
public string GetResourceValue(string key)
|
||||
{
|
||||
|
@@ -3,11 +3,11 @@ using ModernKeePass.Interfaces;
|
||||
|
||||
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)
|
||||
|
@@ -121,6 +121,7 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="DatabaseTests.cs" />
|
||||
<Compile Include="Mock\DatabaseServiceMock.cs" />
|
||||
<Compile Include="Mock\LicenseServiceMock.cs" />
|
||||
<Compile Include="Mock\RecentServiceMock.cs" />
|
||||
<Compile Include="Mock\ResourceServiceMock.cs" />
|
||||
<Compile Include="Mock\SettingsServiceMock.cs" />
|
||||
@@ -131,11 +132,14 @@
|
||||
<AppxManifest Include="Package.appxmanifest">
|
||||
<SubType>Designer</SubType>
|
||||
</AppxManifest>
|
||||
<Content Include="Databases\TestDatabase.kdbx" />
|
||||
<Content Include="Data\TestDatabase.kdbx" />
|
||||
<None Include="ModernKeePassApp.Test_TemporaryKey.pfx" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Data\WindowsStoreProxy.xml">
|
||||
<SubType>Designer</SubType>
|
||||
</Content>
|
||||
<Content Include="Images\UnitTestLogo.scale-100.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
|
@@ -6,14 +6,15 @@ using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
|
||||
using ModernKeePass.ViewModels;
|
||||
using ModernKeePass.Views;
|
||||
using ModernKeePassApp.Test.Mock;
|
||||
using ModernKeePassLib;
|
||||
|
||||
namespace ModernKeePassApp.Test
|
||||
{
|
||||
[TestClass]
|
||||
public class ViewModelsTests
|
||||
{
|
||||
private RecentServiceMock _recent = new RecentServiceMock();
|
||||
private ResourceServiceMock _resource = new ResourceServiceMock();
|
||||
private readonly RecentServiceMock _recent = new RecentServiceMock();
|
||||
private readonly ResourceServiceMock _resource = new ResourceServiceMock();
|
||||
|
||||
[TestMethod]
|
||||
public void TestAboutVm()
|
||||
@@ -32,12 +33,13 @@ namespace ModernKeePassApp.Test
|
||||
var firstGroup = mainVm.MainMenuItems.FirstOrDefault();
|
||||
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);
|
||||
Assert.IsNotNull(mainVm.SelectedItem);
|
||||
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);
|
||||
Assert.IsNotNull(mainVm.SelectedItem);
|
||||
Assert.AreEqual(2, mainVm.MainMenuItems.Count());
|
||||
@@ -61,8 +63,7 @@ namespace ModernKeePassApp.Test
|
||||
{
|
||||
var database = new DatabaseServiceMock
|
||||
{
|
||||
Status = 1,
|
||||
DatabaseFile = Package.Current.InstalledLocation.GetFileAsync(@"Databases\TestDatabase.kdbx")
|
||||
DatabaseFile = Package.Current.InstalledLocation.GetFileAsync(@"Data\TestDatabase.kdbx")
|
||||
.GetAwaiter().GetResult()
|
||||
};
|
||||
var openVm = new OpenVm(database);
|
||||
@@ -79,7 +80,7 @@ namespace ModernKeePassApp.Test
|
||||
public void TestRecentVm()
|
||||
{
|
||||
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");
|
||||
var recentVm = new RecentVm();
|
||||
Assert.IsTrue(recentVm.RecentItems.Count == 1);
|
||||
@@ -88,10 +89,17 @@ namespace ModernKeePassApp.Test
|
||||
mru.Clear();
|
||||
}
|
||||
|
||||
/*[TestMethod]
|
||||
[TestMethod]
|
||||
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]
|
||||
public void TestSettingsVm()
|
||||
@@ -100,10 +108,32 @@ namespace ModernKeePassApp.Test
|
||||
Assert.AreEqual(1, settingsVm.MenuItems.Count());
|
||||
var firstGroup = settingsVm.MenuItems.FirstOrDefault();
|
||||
// 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);
|
||||
var selectedItem = (ListMenuItemVm) settingsVm.SelectedItem;
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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 readonly bool m_bWriting;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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.Text;
|
||||
|
||||
#if ModernKeePassLib || KeePassUAP
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Crypto.Engines;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
#else
|
||||
using System.Security.Cryptography;
|
||||
#endif
|
||||
|
||||
using ModernKeePassLib.Cryptography;
|
||||
using ModernKeePassLib.Native;
|
||||
@@ -134,7 +138,7 @@ namespace ModernKeePassLib.Cryptography.KeyDerivation
|
||||
return null;
|
||||
}
|
||||
|
||||
public static bool TransformKeyManaged(byte[] pbNewKey32, byte[] pbKeySeed32,
|
||||
internal static bool TransformKeyManaged(byte[] pbNewKey32, byte[] pbKeySeed32,
|
||||
ulong uNumRounds)
|
||||
{
|
||||
#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