mirror of
https://github.com/wismna/ModernKeePass.git
synced 2025-10-03 15:40:18 -04:00
WIP Split composite key user control
Some refactoring
This commit is contained in:
@@ -81,7 +81,7 @@
|
||||
<Compile Include="Common\Interfaces\IEntityVm.cs" />
|
||||
<Compile Include="Common\Interfaces\IFileProxy.cs" />
|
||||
<Compile Include="Common\Interfaces\IImportFormat.cs" />
|
||||
<Compile Include="Common\Interfaces\IPasswordProxy.cs" />
|
||||
<Compile Include="Common\Interfaces\ICredentialsProxy.cs" />
|
||||
<Compile Include="Common\Interfaces\IProxyInvocationHandler.cs" />
|
||||
<Compile Include="Common\Interfaces\IRecentProxy.cs" />
|
||||
<Compile Include="Common\Interfaces\IResourceProxy.cs" />
|
||||
|
@@ -2,10 +2,10 @@
|
||||
|
||||
namespace ModernKeePass.Application.Common.Interfaces
|
||||
{
|
||||
public interface IPasswordProxy
|
||||
public interface ICredentialsProxy
|
||||
{
|
||||
string GeneratePassword(PasswordGenerationOptions options);
|
||||
uint EstimatePasswordComplexity(string password);
|
||||
int EstimatePasswordComplexity(string password);
|
||||
byte[] GenerateKeyFile(byte[] additionalEntropy);
|
||||
}
|
||||
}
|
@@ -19,7 +19,8 @@ namespace ModernKeePass.Application.Entry.Models
|
||||
public string Username { get; set; }
|
||||
public string Password { get; set; }
|
||||
public string Notes { get; set; }
|
||||
public Uri Url { get; set; }
|
||||
public string Url { get; set; }
|
||||
public bool HasUrl => !string.IsNullOrEmpty(Url);
|
||||
public Dictionary<string, string> AdditionalFields { get; set; }
|
||||
public List<EntryVm> History { get; set; }
|
||||
public Icon Icon { get; set; }
|
||||
|
@@ -12,10 +12,10 @@ namespace ModernKeePass.Application.Security.Commands.GenerateKeyFile
|
||||
|
||||
public class GenerateKeyFileCommandHandler : IAsyncRequestHandler<GenerateKeyFileCommand>
|
||||
{
|
||||
private readonly IPasswordProxy _security;
|
||||
private readonly ICredentialsProxy _security;
|
||||
private readonly IFileProxy _file;
|
||||
|
||||
public GenerateKeyFileCommandHandler(IPasswordProxy security, IFileProxy file)
|
||||
public GenerateKeyFileCommandHandler(ICredentialsProxy security, IFileProxy file)
|
||||
{
|
||||
_security = security;
|
||||
_file = file;
|
||||
|
@@ -19,9 +19,9 @@ namespace ModernKeePass.Application.Security.Commands.GeneratePassword
|
||||
|
||||
public class GeneratePasswordCommandHandler: IRequestHandler<GeneratePasswordCommand, string>
|
||||
{
|
||||
private readonly IPasswordProxy _security;
|
||||
private readonly ICredentialsProxy _security;
|
||||
|
||||
public GeneratePasswordCommandHandler(IPasswordProxy security)
|
||||
public GeneratePasswordCommandHandler(ICredentialsProxy security)
|
||||
{
|
||||
_security = security;
|
||||
}
|
||||
|
@@ -3,20 +3,20 @@ using ModernKeePass.Application.Common.Interfaces;
|
||||
|
||||
namespace ModernKeePass.Application.Security.Queries.EstimatePasswordComplexity
|
||||
{
|
||||
public class EstimatePasswordComplexityQuery : IRequest<uint>
|
||||
public class EstimatePasswordComplexityQuery : IRequest<int>
|
||||
{
|
||||
public string Password { get; set; }
|
||||
|
||||
public class EstimatePasswordComplexityQueryHandler : IRequestHandler<EstimatePasswordComplexityQuery, uint>
|
||||
public class EstimatePasswordComplexityQueryHandler : IRequestHandler<EstimatePasswordComplexityQuery, int>
|
||||
{
|
||||
private readonly IPasswordProxy _security;
|
||||
private readonly ICredentialsProxy _security;
|
||||
|
||||
public EstimatePasswordComplexityQueryHandler(IPasswordProxy security)
|
||||
public EstimatePasswordComplexityQueryHandler(ICredentialsProxy security)
|
||||
{
|
||||
_security = security;
|
||||
}
|
||||
|
||||
public uint Handle(EstimatePasswordComplexityQuery message)
|
||||
public int Handle(EstimatePasswordComplexityQuery message)
|
||||
{
|
||||
return _security.EstimatePasswordComplexity(message.Password);
|
||||
}
|
||||
|
@@ -9,7 +9,7 @@ namespace ModernKeePass.Domain.Entities
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public string Password { get; set; }
|
||||
public Uri Url { get; set; }
|
||||
public string Url { get; set; }
|
||||
public string Notes { get; set; }
|
||||
public DateTimeOffset ExpirationDate { get; set; }
|
||||
public Dictionary<string, string> AdditionalFields { get; set; } = new Dictionary<string, string>();
|
||||
|
@@ -19,7 +19,7 @@ namespace ModernKeePass.Infrastructure
|
||||
{
|
||||
services.AddSingleton(typeof(IDatabaseProxy), typeof(KeePassDatabaseClient));
|
||||
services.AddTransient(typeof(ICryptographyClient), typeof(KeePassCryptographyClient));
|
||||
services.AddTransient(typeof(IPasswordProxy), typeof(KeePassPasswordClient));
|
||||
services.AddTransient(typeof(ICredentialsProxy), typeof(KeePassCredentialsClient));
|
||||
return services;
|
||||
}
|
||||
|
||||
|
@@ -85,7 +85,7 @@
|
||||
<Compile Include="KeePass\IconMapper.cs" />
|
||||
<Compile Include="KeePass\KeePassCryptographyClient.cs" />
|
||||
<Compile Include="KeePass\KeePassDatabaseClient.cs" />
|
||||
<Compile Include="KeePass\KeePassPasswordClient.cs" />
|
||||
<Compile Include="KeePass\KeePassCredentialsClient.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="UWP\StorageFileClient.cs" />
|
||||
<Compile Include="UWP\UwpRecentFilesClient.cs" />
|
||||
|
@@ -10,7 +10,6 @@ namespace ModernKeePass.Infrastructure.KeePass
|
||||
{
|
||||
public EntryMappingProfile()
|
||||
{
|
||||
Uri url;
|
||||
CreateMap<PwEntry, EntryEntity>()
|
||||
.ForMember(dest => dest.ParentId, opt => opt.MapFrom(src => src.ParentGroup.Uuid.ToHexString()))
|
||||
.ForMember(dest => dest.ParentName, opt => opt.MapFrom(src => src.ParentGroup.Name))
|
||||
@@ -18,12 +17,7 @@ namespace ModernKeePass.Infrastructure.KeePass
|
||||
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => GetEntryValue(src, PwDefs.TitleField)))
|
||||
.ForMember(dest => dest.UserName, opt => opt.MapFrom(src => GetEntryValue(src, PwDefs.UserNameField)))
|
||||
.ForMember(dest => dest.Password, opt => opt.MapFrom(src => GetEntryValue(src, PwDefs.PasswordField)))
|
||||
.ForMember(dest => dest.Url, opt =>
|
||||
{
|
||||
opt.PreCondition(src =>
|
||||
Uri.TryCreate(GetEntryValue(src, PwDefs.UrlField), UriKind.Absolute, out url));
|
||||
opt.MapFrom(src => new Uri(GetEntryValue(src, PwDefs.UrlField)));
|
||||
})
|
||||
.ForMember(dest => dest.Url, opt => opt.MapFrom(src => GetEntryValue(src, PwDefs.UrlField)))
|
||||
.ForMember(dest => dest.Notes, opt => opt.MapFrom(src => GetEntryValue(src, PwDefs.NotesField)))
|
||||
.ForMember(dest => dest.ForegroundColor, opt => opt.MapFrom(src => src.ForegroundColor))
|
||||
.ForMember(dest => dest.BackgroundColor, opt => opt.MapFrom(src => src.BackgroundColor))
|
||||
|
@@ -7,7 +7,7 @@ using ModernKeePassLib.Security;
|
||||
|
||||
namespace ModernKeePass.Infrastructure.KeePass
|
||||
{
|
||||
public class KeePassPasswordClient: IPasswordProxy
|
||||
public class KeePassCredentialsClient: ICredentialsProxy
|
||||
{
|
||||
public string GeneratePassword(PasswordGenerationOptions options)
|
||||
{
|
||||
@@ -35,9 +35,9 @@ namespace ModernKeePass.Infrastructure.KeePass
|
||||
return password.ReadString();
|
||||
}
|
||||
|
||||
public uint EstimatePasswordComplexity(string password)
|
||||
public int EstimatePasswordComplexity(string password)
|
||||
{
|
||||
return QualityEstimation.EstimatePasswordBits(password?.ToCharArray());
|
||||
return (int)QualityEstimation.EstimatePasswordBits(password?.ToCharArray());
|
||||
}
|
||||
|
||||
public byte[] GenerateKeyFile(byte[] additionalEntropy)
|
@@ -1,6 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using ModernKeePass.Application.Group.Models;
|
||||
|
||||
@@ -13,19 +12,11 @@ namespace ModernKeePass.Interfaces
|
||||
string Title { get; set; }
|
||||
IEnumerable<GroupVm> BreadCrumb { get; }
|
||||
bool IsEditMode { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Save changes to Model
|
||||
/// </summary>
|
||||
ICommand SaveCommand { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Move a entity to the destination group
|
||||
/// </summary>
|
||||
/// <param name="destination">The destination to move the entity to</param>
|
||||
Task Move(GroupVm destination);
|
||||
/// <summary>
|
||||
/// Delete from ViewModel
|
||||
/// </summary>
|
||||
Task MarkForDelete(string recycleBinTitle);
|
||||
}
|
||||
}
|
@@ -31,7 +31,7 @@ namespace ModernKeePass.ViewModels
|
||||
set
|
||||
{
|
||||
SetProperty(ref _hasPassword, value);
|
||||
OnPropertyChanged("IsValid");
|
||||
OnPropertyChanged(nameof(IsValid));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,21 +41,11 @@ namespace ModernKeePass.ViewModels
|
||||
set
|
||||
{
|
||||
SetProperty(ref _hasKeyFile, value);
|
||||
OnPropertyChanged("IsValid");
|
||||
OnPropertyChanged(nameof(IsValid));
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasUserAccount
|
||||
{
|
||||
get { return _hasUserAccount; }
|
||||
set
|
||||
{
|
||||
SetProperty(ref _hasUserAccount, value);
|
||||
OnPropertyChanged("IsValid");
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsValid => !_isOpening && (HasPassword || HasKeyFile && KeyFilePath != null || HasUserAccount);
|
||||
public bool IsValid => !_isOpening && (HasPassword || HasKeyFile && KeyFilePath != null);
|
||||
|
||||
public string Status
|
||||
{
|
||||
@@ -103,7 +93,6 @@ namespace ModernKeePass.ViewModels
|
||||
|
||||
private bool _hasPassword;
|
||||
private bool _hasKeyFile;
|
||||
private bool _hasUserAccount;
|
||||
private bool _isOpening;
|
||||
private string _password = string.Empty;
|
||||
private string _status;
|
||||
@@ -160,7 +149,6 @@ namespace ModernKeePass.ViewModels
|
||||
var errorMessage = new StringBuilder($"{_resource.GetResourceValue("CompositeKeyErrorOpen")}\n");
|
||||
if (HasPassword) errorMessage.AppendLine(_resource.GetResourceValue("CompositeKeyErrorUserPassword"));
|
||||
if (HasKeyFile) errorMessage.AppendLine(_resource.GetResourceValue("CompositeKeyErrorUserKeyFile"));
|
||||
if (HasUserAccount) errorMessage.AppendLine(_resource.GetResourceValue("CompositeKeyErrorUserAccount"));
|
||||
UpdateStatus(errorMessage.ToString(), StatusTypes.Error);
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -171,7 +159,7 @@ namespace ModernKeePass.ViewModels
|
||||
finally
|
||||
{
|
||||
_isOpening = false;
|
||||
OnPropertyChanged("IsValid");
|
||||
OnPropertyChanged(nameof(IsValid));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using MediatR;
|
||||
@@ -120,10 +119,10 @@ namespace ModernKeePass.ViewModels
|
||||
|
||||
public string Url
|
||||
{
|
||||
get { return SelectedItem.Url?.ToString(); }
|
||||
get { return SelectedItem.Url; }
|
||||
set
|
||||
{
|
||||
SelectedItem.Url = new Uri(value);
|
||||
SelectedItem.Url = value;
|
||||
SetFieldValue(nameof(Url), value).Wait();
|
||||
}
|
||||
}
|
||||
@@ -216,10 +215,10 @@ namespace ModernKeePass.ViewModels
|
||||
set { SetProperty(ref _isRevealPassword, value); }
|
||||
}
|
||||
|
||||
public ICommand SaveCommand { get; }
|
||||
public ICommand GeneratePasswordCommand { get; }
|
||||
public ICommand MoveCommand { get; }
|
||||
public ICommand RestoreCommand { get; }
|
||||
public RelayCommand SaveCommand { get; }
|
||||
public RelayCommand GeneratePasswordCommand { get; }
|
||||
public RelayCommand MoveCommand { get; }
|
||||
public RelayCommand RestoreCommand { get; }
|
||||
|
||||
private DatabaseVm Database => _mediator.Send(new GetDatabaseQuery()).GetAwaiter().GetResult();
|
||||
|
||||
@@ -286,7 +285,7 @@ namespace ModernKeePass.ViewModels
|
||||
public async Task SetFieldValue(string fieldName, object value)
|
||||
{
|
||||
await _mediator.Send(new SetFieldValueCommand { EntryId = Id, FieldName = fieldName, FieldValue = value });
|
||||
((RelayCommand)SaveCommand).RaiseCanExecuteChanged();
|
||||
SaveCommand.RaiseCanExecuteChanged();
|
||||
_isDirty = true;
|
||||
}
|
||||
|
||||
@@ -300,7 +299,7 @@ namespace ModernKeePass.ViewModels
|
||||
await _mediator.Send(new RestoreHistoryCommand { Entry = History[0], HistoryIndex = History.Count - SelectedIndex });
|
||||
History.Insert(0, SelectedItem);
|
||||
SelectedIndex = 0;
|
||||
((RelayCommand)SaveCommand).RaiseCanExecuteChanged();
|
||||
SaveCommand.RaiseCanExecuteChanged();
|
||||
}
|
||||
|
||||
public async Task DeleteHistory()
|
||||
@@ -308,14 +307,14 @@ namespace ModernKeePass.ViewModels
|
||||
await _mediator.Send(new DeleteHistoryCommand { Entry = History[0], HistoryIndex = History.Count - SelectedIndex });
|
||||
History.RemoveAt(SelectedIndex);
|
||||
SelectedIndex = 0;
|
||||
((RelayCommand)SaveCommand).RaiseCanExecuteChanged();
|
||||
SaveCommand.RaiseCanExecuteChanged();
|
||||
}
|
||||
|
||||
private async Task SaveChanges()
|
||||
{
|
||||
await AddHistory();
|
||||
await _mediator.Send(new SaveDatabaseCommand());
|
||||
((RelayCommand)SaveCommand).RaiseCanExecuteChanged();
|
||||
SaveCommand.RaiseCanExecuteChanged();
|
||||
_isDirty = false;
|
||||
}
|
||||
}
|
||||
|
@@ -4,7 +4,6 @@ using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using MediatR;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
@@ -53,7 +52,7 @@ namespace ModernKeePass.ViewModels
|
||||
set
|
||||
{
|
||||
_mediator.Send(new UpdateGroupCommand {Group = _group, Title = value, Icon = _group.Icon}).Wait();
|
||||
((RelayCommand)SaveCommand).RaiseCanExecuteChanged();
|
||||
SaveCommand.RaiseCanExecuteChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +62,7 @@ namespace ModernKeePass.ViewModels
|
||||
set
|
||||
{
|
||||
_mediator.Send(new UpdateGroupCommand { Group = _group, Title = _group.Title, Icon = (Icon)Enum.Parse(typeof(Icon), value.ToString()) }).Wait();
|
||||
((RelayCommand)SaveCommand).RaiseCanExecuteChanged();
|
||||
SaveCommand.RaiseCanExecuteChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,8 +72,8 @@ namespace ModernKeePass.ViewModels
|
||||
set
|
||||
{
|
||||
SetProperty(ref _isEditMode, value);
|
||||
((RelayCommand)SortEntriesCommand).RaiseCanExecuteChanged();
|
||||
((RelayCommand)SortGroupsCommand).RaiseCanExecuteChanged();
|
||||
SortEntriesCommand.RaiseCanExecuteChanged();
|
||||
SortGroupsCommand.RaiseCanExecuteChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,10 +88,10 @@ namespace ModernKeePass.ViewModels
|
||||
|
||||
public IEnumerable<GroupVm> BreadCrumb { get; }
|
||||
|
||||
public ICommand SaveCommand { get; }
|
||||
public ICommand SortEntriesCommand { get; }
|
||||
public ICommand SortGroupsCommand { get; }
|
||||
public ICommand MoveCommand { get; }
|
||||
public RelayCommand SaveCommand { get; }
|
||||
public RelayCommand SortEntriesCommand { get; }
|
||||
public RelayCommand SortGroupsCommand { get; }
|
||||
public RelayCommand MoveCommand { get; }
|
||||
|
||||
private DatabaseVm Database => _mediator.Send(new GetDatabaseQuery()).GetAwaiter().GetResult();
|
||||
|
||||
@@ -156,7 +155,7 @@ namespace ModernKeePass.ViewModels
|
||||
private async Task SaveChanges()
|
||||
{
|
||||
await _mediator.Send(new SaveDatabaseCommand());
|
||||
((RelayCommand)SaveCommand).RaiseCanExecuteChanged();
|
||||
SaveCommand.RaiseCanExecuteChanged();
|
||||
}
|
||||
|
||||
private async void Entries_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
@@ -179,21 +178,21 @@ namespace ModernKeePass.ViewModels
|
||||
}
|
||||
break;
|
||||
}
|
||||
((RelayCommand)SaveCommand).RaiseCanExecuteChanged();
|
||||
SaveCommand.RaiseCanExecuteChanged();
|
||||
}
|
||||
|
||||
private async Task SortEntriesAsync()
|
||||
{
|
||||
await _mediator.Send(new SortEntriesCommand {Group = _group});
|
||||
OnPropertyChanged(nameof(Entries));
|
||||
((RelayCommand)SaveCommand).RaiseCanExecuteChanged();
|
||||
SaveCommand.RaiseCanExecuteChanged();
|
||||
}
|
||||
|
||||
private async Task SortGroupsAsync()
|
||||
{
|
||||
await _mediator.Send(new SortGroupsCommand {Group = _group});
|
||||
OnPropertyChanged(nameof(Groups));
|
||||
((RelayCommand)SaveCommand).RaiseCanExecuteChanged();
|
||||
SaveCommand.RaiseCanExecuteChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -10,6 +10,7 @@ using ModernKeePass.Domain.AOP;
|
||||
using ModernKeePass.Domain.Dtos;
|
||||
using ModernKeePass.Domain.Interfaces;
|
||||
using ModernKeePass.Models;
|
||||
using ModernKeePass.ViewModels.ListItems;
|
||||
using ModernKeePass.Views;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
|
@@ -6,6 +6,7 @@ using ModernKeePass.Application.Common.Interfaces;
|
||||
using ModernKeePass.Common;
|
||||
using ModernKeePass.Domain.AOP;
|
||||
using ModernKeePass.Domain.Interfaces;
|
||||
using ModernKeePass.ViewModels.ListItems;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
{
|
||||
|
@@ -7,6 +7,7 @@ using ModernKeePass.Application.Common.Interfaces;
|
||||
using ModernKeePass.Application.Database.Queries.GetDatabase;
|
||||
using ModernKeePass.Domain.AOP;
|
||||
using ModernKeePass.Domain.Interfaces;
|
||||
using ModernKeePass.ViewModels.ListItems;
|
||||
using ModernKeePass.Views;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
|
@@ -133,11 +133,10 @@
|
||||
</core:EventTriggerBehavior>
|
||||
</interactivity:Interaction.Behaviors>
|
||||
</MenuFlyoutItem>
|
||||
<MenuFlyoutItem x:Uid="EntryItemCopyUrl">
|
||||
<MenuFlyoutItem x:Uid="EntryItemCopyUrl" IsEnabled="{Binding HasUrl}">
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<core:EventTriggerBehavior EventName="Click">
|
||||
<actions:NavigateToUrlAction Url="{Binding Url}" />
|
||||
<actions:ToastAction x:Uid="ToastCopyUrl" Title="{Binding Title}" />
|
||||
</core:EventTriggerBehavior>
|
||||
</interactivity:Interaction.Behaviors>
|
||||
</MenuFlyoutItem>
|
||||
|
@@ -2,6 +2,7 @@
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
using ModernKeePass.Domain.Dtos;
|
||||
using ModernKeePass.ViewModels;
|
||||
using ModernKeePass.ViewModels.ListItems;
|
||||
|
||||
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
|
||||
|
||||
|
@@ -25,13 +25,13 @@
|
||||
<Border HorizontalAlignment="Left" BorderThickness="1" BorderBrush="AliceBlue" Width="550" Visibility="{Binding IsFileSelected, Converter={StaticResource BooleanToVisibilityConverter}}">
|
||||
<StackPanel Margin="25,0,25,0">
|
||||
<TextBlock Text="{Binding Name}" />
|
||||
<userControls:CompositeKeyUserControl x:Uid="CompositeKeyOpenButton" DatabaseFilePath="{Binding Token}">
|
||||
<userControls:OpenDatabaseUserControl x:Uid="CompositeKeyOpenButton" DatabaseFilePath="{Binding Token}">
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<core:EventTriggerBehavior EventName="ValidationChecked">
|
||||
<core:EventTriggerBehavior EventName="DatabaseOpened">
|
||||
<core:NavigateToPageAction TargetPage="ModernKeePass.Views.GroupDetailPage" />
|
||||
</core:EventTriggerBehavior>
|
||||
</interactivity:Interaction.Behaviors>
|
||||
</userControls:CompositeKeyUserControl>
|
||||
</userControls:OpenDatabaseUserControl>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
|
@@ -43,16 +43,16 @@
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Row="0" Text="{Binding Name}" Padding="5,0,0,0" />
|
||||
<TextBlock Grid.Row="1" Text="{Binding Path}" Padding="5,0,0,0" FontSize="10" />
|
||||
<userControls:CompositeKeyUserControl Grid.Row="2" x:Name="DatabaseUserControl" x:Uid="CompositeKeyOpenButton" HorizontalAlignment="Stretch" MinWidth="400" Margin="0,10,0,0" Visibility="{Binding IsSelected, Converter={StaticResource BooleanToVisibilityConverter}}" DatabaseFilePath="{Binding Token}">
|
||||
<userControls:OpenDatabaseUserControl Grid.Row="2" x:Uid="CompositeKeyOpenButton" HorizontalAlignment="Stretch" MinWidth="400" Margin="0,10,0,0" Visibility="{Binding IsSelected, Converter={StaticResource BooleanToVisibilityConverter}}" DatabaseFilePath="{Binding Token}">
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<core:EventTriggerBehavior EventName="ValidationChecking">
|
||||
<core:EventTriggerBehavior EventName="DatabaseOpening">
|
||||
<core:CallMethodAction TargetObject="{Binding}" MethodName="UpdateAccessTime" />
|
||||
</core:EventTriggerBehavior>
|
||||
<core:EventTriggerBehavior EventName="ValidationChecked">
|
||||
<core:EventTriggerBehavior EventName="DatabaseOpened">
|
||||
<core:NavigateToPageAction TargetPage="ModernKeePass.Views.GroupDetailPage" />
|
||||
</core:EventTriggerBehavior>
|
||||
</interactivity:Interaction.Behaviors>
|
||||
</userControls:CompositeKeyUserControl>
|
||||
</userControls:OpenDatabaseUserControl>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
|
@@ -1,5 +1,6 @@
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using ModernKeePass.ViewModels;
|
||||
using ModernKeePass.ViewModels.ListItems;
|
||||
|
||||
// The Split Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234234
|
||||
|
||||
|
@@ -4,8 +4,8 @@
|
||||
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"
|
||||
xmlns:listItems="using:ModernKeePass.ViewModels.ListItems"
|
||||
mc:Ignorable="d">
|
||||
<Page.Resources>
|
||||
<CollectionViewSource x:Name="RecycleBinGroups" Source="{Binding Groups}" />
|
||||
@@ -16,7 +16,7 @@
|
||||
<converters:NullToBooleanConverter x:Key="NullToBooleanConverter"/>
|
||||
</Page.Resources>
|
||||
<Page.DataContext>
|
||||
<viewModels:SettingsDatabaseVm />
|
||||
<listItems:SettingsDatabaseVm />
|
||||
</Page.DataContext>
|
||||
|
||||
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||
|
@@ -4,13 +4,13 @@
|
||||
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:listItems="using:ModernKeePass.ViewModels.ListItems"
|
||||
mc:Ignorable="d">
|
||||
<Page.Resources>
|
||||
<CollectionViewSource x:Name="KeyDerivations" Source="{Binding FileFormats}" />
|
||||
</Page.Resources>
|
||||
<Page.DataContext>
|
||||
<viewModels:SettingsNewVm />
|
||||
<listItems:SettingsNewVm />
|
||||
</Page.DataContext>
|
||||
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||
<TextBlock x:Uid="SettingsNewDatabaseDesc" Style="{StaticResource TextBlockSettingsHeaderStyle}" Margin="5,0,0,10"/>
|
||||
|
@@ -4,10 +4,10 @@
|
||||
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:listItems="using:ModernKeePass.ViewModels.ListItems"
|
||||
mc:Ignorable="d">
|
||||
<Page.DataContext>
|
||||
<viewModels:SettingsSaveVm />
|
||||
<listItems:SettingsSaveVm />
|
||||
</Page.DataContext>
|
||||
|
||||
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||
|
@@ -0,0 +1,55 @@
|
||||
<UserControl
|
||||
x:Class="ModernKeePass.Views.UserControls.OpenDatabaseUserControl"
|
||||
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:interactivity="using:Microsoft.Xaml.Interactivity"
|
||||
xmlns:core="using:Microsoft.Xaml.Interactions.Core"
|
||||
xmlns:converters="using:ModernKeePass.Converters"
|
||||
xmlns:viewModels="using:ModernKeePass.ViewModels"
|
||||
mc:Ignorable="d" >
|
||||
<UserControl.Resources>
|
||||
<converters:DiscreteIntToSolidColorBrushConverter x:Key="DiscreteIntToSolidColorBrushConverter"/>
|
||||
<converters:EmptyStringToVisibilityConverter x:Key="EmptyStringToVisibilityConverter"/>
|
||||
</UserControl.Resources>
|
||||
<Grid x:Name="Grid">
|
||||
<!-- DataContext is not set at the root of the control because of issues happening when displaying it -->
|
||||
<Grid.DataContext>
|
||||
<viewModels:OpenDatabaseControlVm />
|
||||
</Grid.DataContext>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="50" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="45" />
|
||||
<RowDefinition Height="40" />
|
||||
<RowDefinition Height="40" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<CheckBox Grid.Row="0" Grid.Column="0" IsChecked="{Binding HasPassword, Mode=TwoWay}" />
|
||||
<PasswordBox Grid.Row="0" Grid.Column="1" x:Uid="CompositeKeyPassword" Password="{Binding Password, Mode=TwoWay}" Height="30" IsPasswordRevealButtonEnabled="True" KeyDown="PasswordBox_KeyDown" BorderBrush="{Binding StatusType, Converter={StaticResource DiscreteIntToSolidColorBrushConverter}}" SelectionHighlightColor="{StaticResource MainColor}" >
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<core:EventTriggerBehavior EventName="GotFocus">
|
||||
<core:ChangePropertyAction TargetObject="{Binding}" PropertyName="HasPassword" Value="True" />
|
||||
</core:EventTriggerBehavior>
|
||||
</interactivity:Interaction.Behaviors>
|
||||
</PasswordBox>
|
||||
<CheckBox Grid.Row="1" Grid.Column="0" IsChecked="{Binding HasKeyFile, Mode=TwoWay}" />
|
||||
<HyperlinkButton Grid.Row="1" Grid.Column="1" Margin="-15,0,0,0"
|
||||
Content="{Binding KeyFileText, Mode=OneWay}"
|
||||
IsEnabled="{Binding HasKeyFile, Mode=OneWay}"
|
||||
Click="KeyFileButton_Click"
|
||||
Style="{StaticResource MainColorHyperlinkButton}" />
|
||||
<Button Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="2"
|
||||
Content="{Binding ButtonLabel, ElementName=UserControl}"
|
||||
Click="OpenButton_OnClick"
|
||||
IsEnabled="{Binding IsValid}"
|
||||
Style="{StaticResource MainColorButton}" />
|
||||
<TextBlock Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="3" Height="Auto" FontSize="14" FontWeight="Light"
|
||||
Text="{Binding Status, Mode=OneWay}"
|
||||
Foreground="{Binding StatusType, Mode=OneWay, Converter={StaticResource DiscreteIntToSolidColorBrushConverter}}"
|
||||
Visibility="{Binding Status, Mode=OneWay, Converter={StaticResource EmptyStringToVisibilityConverter}}" />
|
||||
</Grid>
|
||||
</UserControl>
|
134
ModernKeePass/Views/UserControls/OpenDatabaseUserControl.xaml.cs
Normal file
134
ModernKeePass/Views/UserControls/OpenDatabaseUserControl.xaml.cs
Normal file
@@ -0,0 +1,134 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Storage.AccessCache;
|
||||
using Windows.Storage.Pickers;
|
||||
using Windows.System;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Input;
|
||||
using MediatR;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using ModernKeePass.Application.Common.Interfaces;
|
||||
using ModernKeePass.Application.Database.Commands.CloseDatabase;
|
||||
using ModernKeePass.Application.Database.Commands.SaveDatabase;
|
||||
using ModernKeePass.Application.Database.Queries.GetDatabase;
|
||||
using ModernKeePass.Common;
|
||||
using ModernKeePass.Events;
|
||||
using ModernKeePass.Extensions;
|
||||
using ModernKeePass.ViewModels;
|
||||
|
||||
// Pour en savoir plus sur le modèle d'élément Contrôle utilisateur, consultez la page http://go.microsoft.com/fwlink/?LinkId=234236
|
||||
|
||||
namespace ModernKeePass.Views.UserControls
|
||||
{
|
||||
public sealed partial class OpenDatabaseUserControl
|
||||
{
|
||||
private readonly IMediator _mediator;
|
||||
private readonly IResourceProxy _resource;
|
||||
public OpenDatabaseControlVm Model => Grid.DataContext as OpenDatabaseControlVm;
|
||||
|
||||
public string ButtonLabel
|
||||
{
|
||||
get { return (string)GetValue(ButtonLabelProperty); }
|
||||
set { SetValue(ButtonLabelProperty, value); }
|
||||
}
|
||||
public static readonly DependencyProperty ButtonLabelProperty =
|
||||
DependencyProperty.Register(
|
||||
nameof(ButtonLabel),
|
||||
typeof(string),
|
||||
typeof(OpenDatabaseUserControl),
|
||||
new PropertyMetadata("OK", (o, args) => { }));
|
||||
|
||||
public string DatabaseFilePath
|
||||
{
|
||||
get { return (string)GetValue(DatabaseFilePathProperty); }
|
||||
set { SetValue(DatabaseFilePathProperty, value); }
|
||||
}
|
||||
public static readonly DependencyProperty DatabaseFilePathProperty =
|
||||
DependencyProperty.Register(
|
||||
nameof(DatabaseFilePath),
|
||||
typeof(string),
|
||||
typeof(OpenDatabaseUserControl),
|
||||
new PropertyMetadata(null, (o, args) => { }));
|
||||
|
||||
public OpenDatabaseUserControl() : this(App.Services.GetRequiredService<IMediator>(), App.Services.GetRequiredService<IResourceProxy>()) { }
|
||||
|
||||
public OpenDatabaseUserControl(IMediator mediator, IResourceProxy resource)
|
||||
{
|
||||
_mediator = mediator;
|
||||
_resource = resource;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public event EventHandler DatabaseOpening;
|
||||
public event EventHandler<PasswordEventArgs> DatabaseOpened;
|
||||
|
||||
private async void OpenButton_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
DatabaseOpening?.Invoke(this, new EventArgs());
|
||||
|
||||
var database = await _mediator.Send(new GetDatabaseQuery());
|
||||
if (database.IsOpen)
|
||||
{
|
||||
await MessageDialogHelper.ShowActionDialog(_resource.GetResourceValue("MessageDialogDBOpenTitle"),
|
||||
string.Format(_resource.GetResourceValue("MessageDialogDBOpenDesc"), database.Name),
|
||||
_resource.GetResourceValue("MessageDialogDBOpenButtonSave"),
|
||||
_resource.GetResourceValue("MessageDialogDBOpenButtonDiscard"),
|
||||
async command =>
|
||||
{
|
||||
await _mediator.Send(new SaveDatabaseCommand());
|
||||
ToastNotificationHelper.ShowGenericToast(
|
||||
database.Name,
|
||||
_resource.GetResourceValue("ToastSavedMessage"));
|
||||
await _mediator.Send(new CloseDatabaseCommand());
|
||||
await OpenDatabase();
|
||||
},
|
||||
async command =>
|
||||
{
|
||||
await _mediator.Send(new CloseDatabaseCommand());
|
||||
await OpenDatabase();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
await OpenDatabase();
|
||||
}
|
||||
}
|
||||
|
||||
private void PasswordBox_KeyDown(object sender, KeyRoutedEventArgs e)
|
||||
{
|
||||
if (e.Key != VirtualKey.Enter || !Model.IsValid) return;
|
||||
OpenButton_OnClick(sender, e);
|
||||
// Stop the event from triggering twice
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private async void KeyFileButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var picker = new FileOpenPicker
|
||||
{
|
||||
ViewMode = PickerViewMode.List,
|
||||
SuggestedStartLocation = PickerLocationId.DocumentsLibrary
|
||||
};
|
||||
picker.FileTypeFilter.Add("*");
|
||||
|
||||
// Application now has read/write access to the picked file
|
||||
var file = await picker.PickSingleFileAsync();
|
||||
if (file == null) return;
|
||||
|
||||
var token = StorageApplicationPermissions.FutureAccessList.Add(file);
|
||||
Model.KeyFilePath = token;
|
||||
}
|
||||
|
||||
private async Task OpenDatabase()
|
||||
{
|
||||
var oldLabel = ButtonLabel;
|
||||
ButtonLabel = _resource.GetResourceValue("CompositeKeyOpening");
|
||||
if (await Dispatcher.RunTaskAsync(async () => await Model.OpenDatabase(DatabaseFilePath)))
|
||||
{
|
||||
DatabaseOpened?.Invoke(this, new PasswordEventArgs(Model.RootGroupId));
|
||||
}
|
||||
|
||||
ButtonLabel = oldLabel;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,72 @@
|
||||
<UserControl
|
||||
x:Class="ModernKeePass.Views.UserControls.UpdateCredentialsUserControl"
|
||||
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:interactivity="using:Microsoft.Xaml.Interactivity"
|
||||
xmlns:core="using:Microsoft.Xaml.Interactions.Core"
|
||||
xmlns:converters="using:ModernKeePass.Converters"
|
||||
xmlns:viewModels="using:ModernKeePass.ViewModels"
|
||||
mc:Ignorable="d" >
|
||||
<UserControl.Resources>
|
||||
<converters:ProgressBarLegalValuesConverter x:Key="ProgressBarLegalValuesConverter"/>
|
||||
<converters:DoubleToSolidColorBrushConverter x:Key="DoubleToSolidColorBrushConverter"/>
|
||||
<converters:DiscreteIntToSolidColorBrushConverter x:Key="DiscreteIntToSolidColorBrushConverter"/>
|
||||
<converters:EmptyStringToVisibilityConverter x:Key="EmptyStringToVisibilityConverter"/>
|
||||
</UserControl.Resources>
|
||||
<Grid x:Name="Grid">
|
||||
<!-- DataContext is not set at the root of the control because of issues happening when displaying it -->
|
||||
<Grid.DataContext>
|
||||
<viewModels:UpdateCredentialsViewModel />
|
||||
</Grid.DataContext>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="50" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="45" />
|
||||
<RowDefinition Height="40" />
|
||||
<RowDefinition Height="40" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<CheckBox Grid.Row="0" Grid.Column="0" IsChecked="{Binding HasPassword, Mode=TwoWay}" />
|
||||
<PasswordBox Grid.Row="0" Grid.Column="1" x:Uid="CompositeKeyPassword" Password="{Binding Password, Mode=TwoWay}" Height="30" IsPasswordRevealButtonEnabled="True" BorderBrush="{Binding StatusType, Converter={StaticResource DiscreteIntToSolidColorBrushConverter}}" SelectionHighlightColor="{StaticResource MainColor}" >
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<core:EventTriggerBehavior EventName="GotFocus">
|
||||
<core:ChangePropertyAction TargetObject="{Binding}" PropertyName="HasPassword" Value="True" />
|
||||
</core:EventTriggerBehavior>
|
||||
</interactivity:Interaction.Behaviors>
|
||||
</PasswordBox>
|
||||
<PasswordBox Grid.Row="0" Grid.Column="1" x:Uid="CompositeKeyPassword" Password="{Binding Password, Mode=TwoWay}" Height="30" IsPasswordRevealButtonEnabled="True" BorderBrush="{Binding StatusType, Converter={StaticResource DiscreteIntToSolidColorBrushConverter}}" SelectionHighlightColor="{StaticResource MainColor}" />
|
||||
<ProgressBar Grid.Row="0" Grid.Column="1"
|
||||
Maximum="128" VerticalAlignment="Bottom"
|
||||
Value="{Binding PasswordComplexityIndicator, ConverterParameter=0\,128, Converter={StaticResource ProgressBarLegalValuesConverter}, Mode=OneWay}"
|
||||
Foreground="{Binding PasswordComplexityIndicator, ConverterParameter=128, Converter={StaticResource DoubleToSolidColorBrushConverter}, Mode=OneWay}"/>
|
||||
<CheckBox Grid.Row="1" Grid.Column="0" IsChecked="{Binding HasKeyFile, Mode=TwoWay}" />
|
||||
<HyperlinkButton Grid.Row="1" Grid.Column="1" Margin="-15,0,0,0"
|
||||
Content="{Binding KeyFileText, Mode=OneWay}"
|
||||
IsEnabled="{Binding HasKeyFile, Mode=OneWay}"
|
||||
Click="KeyFileButton_Click"
|
||||
Style="{StaticResource MainColorHyperlinkButton}" />
|
||||
<HyperlinkButton Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right"
|
||||
IsEnabled="{Binding HasKeyFile, Mode=OneWay}"
|
||||
Style="{StaticResource MainColorHyperlinkButton}"
|
||||
Click="CreateKeyFileButton_Click">
|
||||
<SymbolIcon Symbol="Add">
|
||||
<ToolTipService.ToolTip>
|
||||
<ToolTip x:Uid="CompositeKeyNewKeyFileTooltip" />
|
||||
</ToolTipService.ToolTip>
|
||||
</SymbolIcon>
|
||||
</HyperlinkButton>
|
||||
<Button Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="2"
|
||||
x:Uid="UpdateCredentialsOkButton"
|
||||
Click="UpdateButton_OnClick"
|
||||
Style="{StaticResource MainColorButton}"
|
||||
IsEnabled="{Binding IsValid, Mode=OneWay}" />
|
||||
<TextBlock Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="3" Height="Auto" FontSize="14" FontWeight="Light"
|
||||
Text="{Binding Status, Mode=OneWay}"
|
||||
Foreground="{Binding StatusType, Mode=OneWay, Converter={StaticResource DiscreteIntToSolidColorBrushConverter}}"
|
||||
Visibility="{Binding Status, Mode=OneWay, Converter={StaticResource EmptyStringToVisibilityConverter}}" />
|
||||
</Grid>
|
||||
</UserControl>
|
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Windows.Storage.AccessCache;
|
||||
using Windows.Storage.Pickers;
|
||||
using Windows.UI.Xaml;
|
||||
using ModernKeePass.Domain.Dtos;
|
||||
using ModernKeePass.ViewModels;
|
||||
using ModernKeePass.Extensions;
|
||||
|
||||
// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236
|
||||
|
||||
namespace ModernKeePass.Views.UserControls
|
||||
{
|
||||
public sealed partial class UpdateCredentialsUserControl
|
||||
{
|
||||
public UpdateCredentialsViewModel ViewModel => Grid.DataContext as UpdateCredentialsViewModel;
|
||||
public string DatabaseFilePath
|
||||
{
|
||||
get { return (string) GetValue(DatabaseFilePathProperty); }
|
||||
set { SetValue(DatabaseFilePathProperty, value); }
|
||||
}
|
||||
public static readonly DependencyProperty DatabaseFilePathProperty =
|
||||
DependencyProperty.Register(
|
||||
"DatabaseFilePath",
|
||||
typeof(string),
|
||||
typeof(UpdateCredentialsUserControl),
|
||||
new PropertyMetadata(null, (o, args) => { }));
|
||||
|
||||
public event EventHandler CredentialsUpdated;
|
||||
|
||||
public UpdateCredentialsUserControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private async void KeyFileButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var picker =
|
||||
new FileOpenPicker
|
||||
{
|
||||
ViewMode = PickerViewMode.List,
|
||||
SuggestedStartLocation = PickerLocationId.DocumentsLibrary
|
||||
};
|
||||
picker.FileTypeFilter.Add(".key");
|
||||
|
||||
// Application now has read/write access to the picked file
|
||||
var file = await picker.PickSingleFileAsync();
|
||||
if (file == null) return;
|
||||
|
||||
var token = StorageApplicationPermissions.FutureAccessList.Add(file);
|
||||
ViewModel.KeyFilePath = token;
|
||||
}
|
||||
|
||||
private async void CreateKeyFileButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var savePicker = new FileSavePicker
|
||||
{
|
||||
SuggestedStartLocation = PickerLocationId.DocumentsLibrary,
|
||||
SuggestedFileName = "Key"
|
||||
};
|
||||
savePicker.FileTypeChoices.Add("Key file", new List<string> { ".key" });
|
||||
|
||||
var file = await savePicker.PickSaveFileAsync();
|
||||
if (file == null) return;
|
||||
|
||||
var token = StorageApplicationPermissions.FutureAccessList.Add(file);
|
||||
ViewModel.KeyFilePath = token;
|
||||
}
|
||||
|
||||
private async void UpdateButton_OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
//throw new NotImplementedException();
|
||||
|
||||
if (await Dispatcher.RunTaskAsync(async () =>
|
||||
{
|
||||
var fileInfo = new FileInfo
|
||||
{
|
||||
Path = DatabaseFilePath
|
||||
};
|
||||
await ViewModel.CreateDatabase(fileInfo);
|
||||
return true;
|
||||
}))
|
||||
{
|
||||
CredentialsUpdated?.Invoke(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -94,7 +94,6 @@
|
||||
</Compile>
|
||||
<Compile Include="DependencyInjection.cs" />
|
||||
<Compile Include="Models\NavigationItem.cs" />
|
||||
<Compile Include="ViewModels\Items\SettingsSaveVm.cs" />
|
||||
<Compile Include="Views\MainPageFrames\DonatePage.xaml.cs">
|
||||
<DependentUpon>DonatePage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
@@ -144,9 +143,6 @@
|
||||
</Compile>
|
||||
<Compile Include="ViewModels\AboutVm.cs" />
|
||||
<Compile Include="ViewModels\CompositeKeyVm.cs" />
|
||||
<Compile Include="ViewModels\Items\ListMenuItemVm.cs" />
|
||||
<Compile Include="ViewModels\Items\MainMenuItemVm.cs" />
|
||||
<Compile Include="ViewModels\Items\RecentItemVm.cs" />
|
||||
<Compile Include="Views\EntryDetailPage.xaml.cs">
|
||||
<DependentUpon>EntryDetailPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
@@ -165,14 +161,15 @@
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="ViewModels\EntryDetailVm.cs" />
|
||||
<Compile Include="ViewModels\GroupDetailVm.cs" />
|
||||
<Compile Include="ViewModels\Items\SettingsNewVm.cs" />
|
||||
<Compile Include="ViewModels\SettingsVm.cs" />
|
||||
<Compile Include="ViewModels\MainVm.cs" />
|
||||
<Compile Include="ViewModels\NewVm.cs" />
|
||||
<Compile Include="ViewModels\OpenVm.cs" />
|
||||
<Compile Include="ViewModels\RecentVm.cs" />
|
||||
<Compile Include="ViewModels\SaveVm.cs" />
|
||||
<Compile Include="ViewModels\Items\SettingsDatabaseVm.cs" />
|
||||
<Compile Include="Views\UserControls\OpenDatabaseUserControl.xaml.cs">
|
||||
<DependentUpon>OpenDatabaseUserControl.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Views\UserControls\HamburgerMenuUserControl.xaml.cs">
|
||||
<DependentUpon>HamburgerMenuUserControl.xaml</DependentUpon>
|
||||
</Compile>
|
||||
@@ -182,6 +179,9 @@
|
||||
<Compile Include="Views\UserControls\TopMenuUserControl.xaml.cs">
|
||||
<DependentUpon>TopMenuUserControl.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Views\UserControls\UpdateCredentialsUserControl.xaml.cs">
|
||||
<DependentUpon>UpdateCredentialsUserControl.xaml</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AppxManifest Include="Package.appxmanifest">
|
||||
@@ -314,6 +314,10 @@
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Page>
|
||||
<Page Include="Views\UserControls\OpenDatabaseUserControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="Views\UserControls\HamburgerMenuUserControl.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
@@ -326,6 +330,10 @@
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Views\UserControls\UpdateCredentialsUserControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="AutoMapper, Version=5.2.0.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">
|
||||
|
@@ -1,19 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" IgnorableNamespaces= "uap mp">
|
||||
<Identity Name="wismna.ModernKeePass" Publisher="CN=0719A91A-C322-4EE0-A257-E60733EECF06" Version="2.0.0.0" />
|
||||
<mp:PhoneIdentity PhoneProductId="0EFC7A82-E22B-471E-A576-65FCCDD6E449" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
|
||||
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" IgnorableNamespaces="uap mp">
|
||||
<Identity Name="wismna.KayPee" Publisher="CN=0719A91A-C322-4EE0-A257-E60733EECF06" Version="2.0.0.0" />
|
||||
<mp:PhoneIdentity PhoneProductId="0EFC7A82-E22B-471E-A576-65FCCDD6E449" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
|
||||
<Dependencies>
|
||||
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.17134.0" MaxVersionTested="10.0.17134.0" />
|
||||
</Dependencies>
|
||||
<Properties>
|
||||
<DisplayName>ModernKeePass</DisplayName>
|
||||
<DisplayName>KayPee</DisplayName>
|
||||
<PublisherDisplayName>wismna</PublisherDisplayName>
|
||||
<Logo>Assets\StoreLogo.png</Logo>
|
||||
</Properties>
|
||||
<Resources>
|
||||
<Resource Language="x-generate" />
|
||||
<Resource uap:Scale="180"/>
|
||||
<Resource uap:DXFeatureLevel="dx11"/>
|
||||
<Resource uap:Scale="180" />
|
||||
<Resource uap:DXFeatureLevel="dx11" />
|
||||
</Resources>
|
||||
<Applications>
|
||||
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="ModernKeePass.App">
|
||||
@@ -23,22 +23,6 @@
|
||||
<uap:SplashScreen Image="Assets\ModernKeePass-SplashScreen.png" BackgroundColor="#7755c4" />
|
||||
</uap:VisualElements>
|
||||
<Extensions>
|
||||
<uap:Extension Category="windows.fileOpenPicker">
|
||||
<uap:FileOpenPicker>
|
||||
<uap:SupportedFileTypes>
|
||||
<uap:FileType>.kdbx</uap:FileType>
|
||||
</uap:SupportedFileTypes>
|
||||
</uap:FileOpenPicker>
|
||||
</uap:Extension>
|
||||
<uap:Extension Category="windows.fileTypeAssociation">
|
||||
<uap:FileTypeAssociation Name="kdbx">
|
||||
<uap:DisplayName>KeePass 2.x database</uap:DisplayName>
|
||||
<uap:EditFlags OpenIsSafe="true" />
|
||||
<uap:SupportedFileTypes>
|
||||
<uap:FileType ContentType="application/xml">.kdbx</uap:FileType>
|
||||
</uap:SupportedFileTypes>
|
||||
</uap:FileTypeAssociation>
|
||||
</uap:Extension>
|
||||
<uap:Extension Category="windows.fileSavePicker">
|
||||
<uap:FileSavePicker>
|
||||
<uap:SupportedFileTypes>
|
||||
@@ -46,6 +30,21 @@
|
||||
</uap:SupportedFileTypes>
|
||||
</uap:FileSavePicker>
|
||||
</uap:Extension>
|
||||
<uap:Extension Category="windows.fileTypeAssociation">
|
||||
<uap:FileTypeAssociation Name="kdbx">
|
||||
<uap:DisplayName>KeePass 2.x database</uap:DisplayName>
|
||||
<uap:SupportedFileTypes>
|
||||
<uap:FileType ContentType="application/xml">.kdbx</uap:FileType>
|
||||
</uap:SupportedFileTypes>
|
||||
</uap:FileTypeAssociation>
|
||||
</uap:Extension>
|
||||
<uap:Extension Category="windows.fileOpenPicker">
|
||||
<uap:FileOpenPicker>
|
||||
<uap:SupportedFileTypes>
|
||||
<uap:FileType>.kdbx</uap:FileType>
|
||||
</uap:SupportedFileTypes>
|
||||
</uap:FileOpenPicker>
|
||||
</uap:Extension>
|
||||
</Extensions>
|
||||
</Application>
|
||||
</Applications>
|
||||
|
@@ -1,31 +0,0 @@
|
||||
using System;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using ModernKeePass.Application.Common.Interfaces;
|
||||
using ModernKeePass.Domain.AOP;
|
||||
using ModernKeePass.Domain.Interfaces;
|
||||
|
||||
namespace ModernKeePass.ViewModels.ListItems
|
||||
{
|
||||
public class ListMenuItemViewModel : NotifyPropertyChangedBase, IIsEnabled, ISelectableModel
|
||||
{
|
||||
private bool _isSelected;
|
||||
|
||||
public string Title { get; set; }
|
||||
|
||||
public string Group { get; set; } = "_";
|
||||
public Type PageType { get; set; }
|
||||
public Symbol SymbolIcon { get; set; }
|
||||
public bool IsEnabled { get; set; } = true;
|
||||
|
||||
public bool IsSelected
|
||||
{
|
||||
get => _isSelected;
|
||||
set => SetProperty(ref _isSelected, value);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Title;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,10 +0,0 @@
|
||||
using Windows.UI.Xaml.Controls;
|
||||
|
||||
namespace ModernKeePass.ViewModels.ListItems
|
||||
{
|
||||
public class MainMenuItemViewModel: ListMenuItemViewModel
|
||||
{
|
||||
public object Parameter { get; set; }
|
||||
public Frame Destination { get; set; }
|
||||
}
|
||||
}
|
@@ -1,36 +0,0 @@
|
||||
using System.Threading.Tasks;
|
||||
using Autofac;
|
||||
using ModernKeePass.Application.Common.Interfaces;
|
||||
using ModernKeePass.Domain.AOP;
|
||||
using ModernKeePass.Domain.Interfaces;
|
||||
|
||||
namespace ModernKeePass.ViewModels.ListItems
|
||||
{
|
||||
public class RecentItemViewModel: NotifyPropertyChangedBase, ISelectableModel
|
||||
{
|
||||
private readonly IRecentService _recentService;
|
||||
private bool _isSelected;
|
||||
|
||||
public string Token { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
||||
public bool IsSelected
|
||||
{
|
||||
get => _isSelected;
|
||||
set => SetProperty(ref _isSelected, value);
|
||||
}
|
||||
|
||||
public RecentItemViewModel(): this (App.Container.Resolve<IRecentService>())
|
||||
{ }
|
||||
|
||||
public RecentItemViewModel(IRecentService recentService)
|
||||
{
|
||||
_recentService = recentService;
|
||||
}
|
||||
|
||||
public async Task UpdateAccessTime()
|
||||
{
|
||||
await _recentService.Get(Token);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,101 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using Autofac;
|
||||
using ModernKeePass.Domain.AOP;
|
||||
using ModernKeePass.Domain.Entities;
|
||||
using ModernKeePass.Domain.Interfaces;
|
||||
|
||||
namespace ModernKeePass.ViewModels.ListItems
|
||||
{
|
||||
// TODO: implement Kdf settings
|
||||
public class SettingsDatabaseViewModel: NotifyPropertyChangedBase
|
||||
{
|
||||
private readonly IDatabaseService _databaseService;
|
||||
private readonly ICryptographyService _cryptographyService;
|
||||
|
||||
public bool HasRecycleBin
|
||||
{
|
||||
get => _databaseService.IsRecycleBinEnabled;
|
||||
set {
|
||||
// TODO: do something here
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsNewRecycleBin
|
||||
{
|
||||
get => _databaseService.RecycleBin == null;
|
||||
set
|
||||
{
|
||||
// TODO: make this work
|
||||
if (value) _databaseService.AddEntity(_databaseService.RootGroupEntity, new Entity{Name = "Recycle Bin"});
|
||||
}
|
||||
}
|
||||
|
||||
public ObservableCollection<GroupEntity> Groups { get; set; }
|
||||
|
||||
public ObservableCollection<Entity> Ciphers => new ObservableCollection<Entity>(_cryptographyService.Ciphers);
|
||||
|
||||
public IEnumerable<string> Compressions => _cryptographyService.CompressionAlgorithms;
|
||||
|
||||
public IEnumerable<Entity> KeyDerivations => _cryptographyService.KeyDerivations;
|
||||
|
||||
public Entity SelectedCipher
|
||||
{
|
||||
get => Ciphers.FirstOrDefault(c => c.Id == _databaseService.Cipher.Id);
|
||||
set
|
||||
{
|
||||
if (_databaseService.Cipher != value)
|
||||
{
|
||||
_databaseService.Cipher = value;
|
||||
//OnPropertyChanged(nameof(SelectedCipher));
|
||||
}
|
||||
}
|
||||
}
|
||||
public Entity SelectedKeyDerivation
|
||||
{
|
||||
get => _databaseService.KeyDerivation;
|
||||
set
|
||||
{
|
||||
if (_databaseService.KeyDerivation != value)
|
||||
{
|
||||
_databaseService.KeyDerivation = value;
|
||||
OnPropertyChanged(nameof(SelectedKeyDerivation));
|
||||
}
|
||||
}
|
||||
}
|
||||
public string SelectedCompression
|
||||
{
|
||||
get => _databaseService.Compression;
|
||||
set
|
||||
{
|
||||
if (_databaseService.Compression != value)
|
||||
{
|
||||
_databaseService.Compression = value;
|
||||
OnPropertyChanged(nameof(SelectedCompression));
|
||||
}
|
||||
}
|
||||
}
|
||||
public GroupEntity SelectedRecycleBin
|
||||
{
|
||||
get => _databaseService.RecycleBin;
|
||||
set
|
||||
{
|
||||
if (_databaseService.RecycleBin != value)
|
||||
{
|
||||
_databaseService.RecycleBin = value;
|
||||
OnPropertyChanged(nameof(SelectedRecycleBin));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public SettingsDatabaseViewModel() : this(App.Container.Resolve<IDatabaseService>(), App.Container.Resolve<ICryptographyService>()) { }
|
||||
|
||||
public SettingsDatabaseViewModel(IDatabaseService databaseService, ICryptographyService cryptographyService)
|
||||
{
|
||||
_databaseService = databaseService;
|
||||
_cryptographyService = cryptographyService;
|
||||
Groups = new ObservableCollection<GroupEntity>(_databaseService.RootGroupEntity.SubGroups);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,33 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using Autofac;
|
||||
using ModernKeePass.Domain.Interfaces;
|
||||
|
||||
namespace ModernKeePass.ViewModels.ListItems
|
||||
{
|
||||
public class SettingsNewViewModel
|
||||
{
|
||||
private readonly ISettingsService _settings;
|
||||
|
||||
public SettingsNewViewModel() : this(App.Container.Resolve<ISettingsService>())
|
||||
{ }
|
||||
|
||||
public SettingsNewViewModel(ISettingsService settings)
|
||||
{
|
||||
_settings = settings;
|
||||
}
|
||||
|
||||
public bool IsCreateSample
|
||||
{
|
||||
get => _settings.GetSetting<bool>("Sample");
|
||||
set => _settings.PutSetting("Sample", value);
|
||||
}
|
||||
|
||||
public IEnumerable<string> FileFormats => new []{"2", "4"};
|
||||
|
||||
public string FileFormatVersion
|
||||
{
|
||||
get => _settings.GetSetting("DefaultFileFormat", "2");
|
||||
set => _settings.PutSetting("DefaultFileFormat", value);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,24 +0,0 @@
|
||||
using Autofac;
|
||||
using ModernKeePass.Domain.Interfaces;
|
||||
|
||||
namespace ModernKeePass.ViewModels.ListItems
|
||||
{
|
||||
public class SettingsSaveViewModel
|
||||
{
|
||||
private readonly ISettingsService _settings;
|
||||
|
||||
public SettingsSaveViewModel() : this(App.Container.Resolve<ISettingsService>())
|
||||
{ }
|
||||
|
||||
public SettingsSaveViewModel(ISettingsService settings)
|
||||
{
|
||||
_settings = settings;
|
||||
}
|
||||
|
||||
public bool IsSaveSuspend
|
||||
{
|
||||
get => _settings.GetSetting("SaveSuspend", true);
|
||||
set => _settings.PutSetting("SaveSuspend", value);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,322 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Windows.Input;
|
||||
using ModernKeePass.Common;
|
||||
using ModernKeePass.Interfaces;
|
||||
using ModernKeePass.Services;
|
||||
using ModernKeePassLib;
|
||||
using ModernKeePassLib.Cryptography.PasswordGenerator;
|
||||
using ModernKeePassLib.Security;
|
||||
using ModernKeePassLib.Cryptography;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
{
|
||||
public class EntryVm : INotifyPropertyChanged, IPwEntity, ISelectableModel
|
||||
{
|
||||
public GroupVm ParentGroup { get; private set; }
|
||||
public GroupVm PreviousGroup { get; private set; }
|
||||
public bool IsRevealPasswordEnabled => !string.IsNullOrEmpty(Password);
|
||||
public bool HasExpired => HasExpirationDate && _pwEntry.ExpiryTime < DateTime.Now;
|
||||
public double PasswordComplexityIndicator => QualityEstimation.EstimatePasswordBits(Password?.ToCharArray());
|
||||
public bool UpperCasePatternSelected { get; set; } = true;
|
||||
public bool LowerCasePatternSelected { get; set; } = true;
|
||||
public bool DigitsPatternSelected { get; set; } = true;
|
||||
public bool MinusPatternSelected { get; set; }
|
||||
public bool UnderscorePatternSelected { get; set; }
|
||||
public bool SpacePatternSelected { get; set; }
|
||||
public bool SpecialPatternSelected { get; set; }
|
||||
public bool BracketsPatternSelected { get; set; }
|
||||
public string CustomChars { get; set; } = string.Empty;
|
||||
public PwUuid IdUuid => _pwEntry?.Uuid;
|
||||
public string Id => _pwEntry?.Uuid.ToHexString();
|
||||
public bool IsRecycleOnDelete => _database.IsRecycleBinEnabled && !ParentGroup.IsSelected;
|
||||
public IEnumerable<IPwEntity> BreadCrumb => new List<IPwEntity>(ParentGroup.BreadCrumb) {ParentGroup};
|
||||
/// <summary>
|
||||
/// Determines if the Entry is current or from history
|
||||
/// </summary>
|
||||
public bool IsSelected { get; set; } = true;
|
||||
|
||||
public double PasswordLength
|
||||
{
|
||||
get => _passwordLength;
|
||||
set
|
||||
{
|
||||
_passwordLength = value;
|
||||
NotifyPropertyChanged("PasswordLength");
|
||||
}
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get => GetEntryValue(PwDefs.TitleField);
|
||||
set => SetEntryValue(PwDefs.TitleField, new ProtectedString(true, value));
|
||||
}
|
||||
|
||||
|
||||
public string UserName
|
||||
{
|
||||
get => GetEntryValue(PwDefs.UserNameField);
|
||||
set => SetEntryValue(PwDefs.UserNameField, new ProtectedString(true, value));
|
||||
}
|
||||
|
||||
public string Password
|
||||
{
|
||||
get => GetEntryValue(PwDefs.PasswordField);
|
||||
set
|
||||
{
|
||||
SetEntryValue(PwDefs.PasswordField, new ProtectedString(true, value));
|
||||
NotifyPropertyChanged("Password");
|
||||
NotifyPropertyChanged("PasswordComplexityIndicator");
|
||||
}
|
||||
}
|
||||
|
||||
public string Url
|
||||
{
|
||||
get => GetEntryValue(PwDefs.UrlField);
|
||||
set => SetEntryValue(PwDefs.UrlField, new ProtectedString(true, value));
|
||||
}
|
||||
|
||||
public string Notes
|
||||
{
|
||||
get => GetEntryValue(PwDefs.NotesField);
|
||||
set => SetEntryValue(PwDefs.NotesField, new ProtectedString(true, value));
|
||||
}
|
||||
|
||||
public int IconId
|
||||
{
|
||||
get
|
||||
{
|
||||
if (HasExpired) return (int) PwIcon.Expired;
|
||||
if (_pwEntry?.IconId != null) return (int) _pwEntry?.IconId;
|
||||
return -1;
|
||||
}
|
||||
set
|
||||
{
|
||||
HandleBackup();
|
||||
_pwEntry.IconId = (PwIcon)value;
|
||||
}
|
||||
}
|
||||
|
||||
public DateTimeOffset ExpiryDate
|
||||
{
|
||||
get => new DateTimeOffset(_pwEntry.ExpiryTime.Date);
|
||||
set
|
||||
{
|
||||
if (!HasExpirationDate) return;
|
||||
HandleBackup();
|
||||
_pwEntry.ExpiryTime = value.DateTime;
|
||||
}
|
||||
}
|
||||
|
||||
public TimeSpan ExpiryTime
|
||||
{
|
||||
get => _pwEntry.ExpiryTime.TimeOfDay;
|
||||
set
|
||||
{
|
||||
if (!HasExpirationDate) return;
|
||||
HandleBackup();
|
||||
_pwEntry.ExpiryTime = _pwEntry.ExpiryTime.Date.Add(value);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsEditMode
|
||||
{
|
||||
get => IsSelected && _isEditMode;
|
||||
set
|
||||
{
|
||||
_isEditMode = value;
|
||||
NotifyPropertyChanged("IsEditMode");
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsVisible
|
||||
{
|
||||
get => _isVisible;
|
||||
set
|
||||
{
|
||||
_isVisible = value;
|
||||
NotifyPropertyChanged("IsVisible");
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsRevealPassword
|
||||
{
|
||||
get => _isRevealPassword;
|
||||
set
|
||||
{
|
||||
_isRevealPassword = value;
|
||||
NotifyPropertyChanged("IsRevealPassword");
|
||||
}
|
||||
}
|
||||
public bool HasExpirationDate
|
||||
{
|
||||
get => _pwEntry.Expires;
|
||||
set
|
||||
{
|
||||
_pwEntry.Expires = value;
|
||||
NotifyPropertyChanged("HasExpirationDate");
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<IPwEntity> History
|
||||
{
|
||||
get
|
||||
{
|
||||
var history = new Stack<EntryVm>();
|
||||
foreach (var historyEntry in _pwEntry.History)
|
||||
{
|
||||
history.Push(new EntryVm(historyEntry, ParentGroup) {IsSelected = false});
|
||||
}
|
||||
history.Push(this);
|
||||
|
||||
return history;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Color? BackgroundColor
|
||||
{
|
||||
get => _pwEntry?.BackgroundColor;
|
||||
set
|
||||
{
|
||||
if (value != null) _pwEntry.BackgroundColor = (Color) value;
|
||||
}
|
||||
}
|
||||
|
||||
public Color? ForegroundColor
|
||||
{
|
||||
get => _pwEntry?.ForegroundColor;
|
||||
set
|
||||
{
|
||||
if (value != null) _pwEntry.ForegroundColor = (Color)value;
|
||||
}
|
||||
}
|
||||
|
||||
public ICommand SaveCommand { get; }
|
||||
public ICommand GeneratePasswordCommand { get; }
|
||||
public ICommand UndoDeleteCommand { get; }
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
private readonly PwEntry _pwEntry;
|
||||
private readonly IDatabaseService _database;
|
||||
private readonly IResourceService _resource;
|
||||
private bool _isEditMode;
|
||||
private bool _isDirty = true;
|
||||
private bool _isRevealPassword;
|
||||
private double _passwordLength = 25;
|
||||
private bool _isVisible = true;
|
||||
|
||||
private void NotifyPropertyChanged(string propertyName)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
public EntryVm() { }
|
||||
|
||||
internal EntryVm(PwEntry entry, GroupVm parent) : this(entry, parent, DatabaseService.Instance, new ResourcesService()) { }
|
||||
|
||||
public EntryVm(PwEntry entry, GroupVm parent, IDatabaseService database, IResourceService resource)
|
||||
{
|
||||
_database = database;
|
||||
_resource = resource;
|
||||
_pwEntry = entry;
|
||||
ParentGroup = parent;
|
||||
|
||||
SaveCommand = new RelayCommand(() => _database.Save());
|
||||
GeneratePasswordCommand = new RelayCommand(GeneratePassword);
|
||||
UndoDeleteCommand = new RelayCommand(() => Move(PreviousGroup), () => PreviousGroup != null);
|
||||
}
|
||||
|
||||
public void GeneratePassword()
|
||||
{
|
||||
var pwProfile = new PwProfile
|
||||
{
|
||||
GeneratorType = PasswordGeneratorType.CharSet,
|
||||
Length = (uint)PasswordLength,
|
||||
CharSet = new PwCharSet()
|
||||
};
|
||||
|
||||
if (UpperCasePatternSelected) pwProfile.CharSet.Add(PwCharSet.UpperCase);
|
||||
if (LowerCasePatternSelected) pwProfile.CharSet.Add(PwCharSet.LowerCase);
|
||||
if (DigitsPatternSelected) pwProfile.CharSet.Add(PwCharSet.Digits);
|
||||
if (SpecialPatternSelected) pwProfile.CharSet.Add(PwCharSet.SpecialChars);
|
||||
if (MinusPatternSelected) pwProfile.CharSet.Add('-');
|
||||
if (UnderscorePatternSelected) pwProfile.CharSet.Add('_');
|
||||
if (SpacePatternSelected) pwProfile.CharSet.Add(' ');
|
||||
if (BracketsPatternSelected) pwProfile.CharSet.Add(PwCharSet.Brackets);
|
||||
|
||||
pwProfile.CharSet.Add(CustomChars);
|
||||
|
||||
ProtectedString password;
|
||||
PwGenerator.Generate(out password, pwProfile, null, new CustomPwGeneratorPool());
|
||||
|
||||
SetEntryValue(PwDefs.PasswordField, password);
|
||||
NotifyPropertyChanged("Password");
|
||||
NotifyPropertyChanged("IsRevealPasswordEnabled");
|
||||
NotifyPropertyChanged("PasswordComplexityIndicator");
|
||||
}
|
||||
|
||||
|
||||
public void MarkForDelete(string recycleBinTitle)
|
||||
{
|
||||
if (_database.IsRecycleBinEnabled && _database.RecycleBin?.IdUuid == null)
|
||||
_database.CreateRecycleBin(recycleBinTitle);
|
||||
Move(_database.IsRecycleBinEnabled && !ParentGroup.IsSelected ? _database.RecycleBin : null);
|
||||
}
|
||||
|
||||
public void Move(GroupVm destination)
|
||||
{
|
||||
PreviousGroup = ParentGroup;
|
||||
PreviousGroup.Entries.Remove(this);
|
||||
if (destination == null)
|
||||
{
|
||||
_database.AddDeletedItem(IdUuid);
|
||||
return;
|
||||
}
|
||||
ParentGroup = destination;
|
||||
ParentGroup.Entries.Add(this);
|
||||
}
|
||||
|
||||
public void CommitDelete()
|
||||
{
|
||||
_pwEntry.ParentGroup.Entries.Remove(_pwEntry);
|
||||
if (!_database.IsRecycleBinEnabled || PreviousGroup.IsSelected) _database.AddDeletedItem(IdUuid);
|
||||
}
|
||||
|
||||
public PwEntry GetPwEntry()
|
||||
{
|
||||
return _pwEntry;
|
||||
}
|
||||
public void Reset()
|
||||
{
|
||||
_isDirty = false;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return IsSelected ? _resource.GetResourceValue("EntryCurrent") : _pwEntry.LastModificationTime.ToString("g");
|
||||
}
|
||||
|
||||
private void HandleBackup()
|
||||
{
|
||||
if (_isDirty) return;
|
||||
_pwEntry?.Touch(true);
|
||||
_pwEntry?.CreateBackup(null);
|
||||
_isDirty = true;
|
||||
}
|
||||
|
||||
private string GetEntryValue(string key)
|
||||
{
|
||||
return _pwEntry?.Strings.GetSafe(key).ReadString();
|
||||
}
|
||||
|
||||
private void SetEntryValue(string key, ProtectedString newValue)
|
||||
{
|
||||
HandleBackup();
|
||||
_pwEntry?.Strings.Set(key, newValue);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,257 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using ModernKeePass.Common;
|
||||
using ModernKeePass.Interfaces;
|
||||
using ModernKeePass.Services;
|
||||
using ModernKeePassLib;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
{
|
||||
public class GroupVm : NotifyPropertyChangedBase, IPwEntity, ISelectableModel
|
||||
{
|
||||
public GroupVm ParentGroup { get; private set; }
|
||||
public GroupVm PreviousGroup { get; private set; }
|
||||
|
||||
public ObservableCollection<EntryVm> Entries
|
||||
{
|
||||
get => _entries;
|
||||
private set => SetProperty(ref _entries, value);
|
||||
}
|
||||
|
||||
public IEnumerable<EntryVm> SubEntries
|
||||
{
|
||||
get
|
||||
{
|
||||
var subEntries = new List<EntryVm>();
|
||||
subEntries.AddRange(Entries);
|
||||
foreach (var group in Groups)
|
||||
{
|
||||
subEntries.AddRange(group.SubEntries);
|
||||
}
|
||||
|
||||
return subEntries;
|
||||
}
|
||||
}
|
||||
|
||||
public ObservableCollection<GroupVm> Groups { get; set; } = new ObservableCollection<GroupVm>();
|
||||
|
||||
public PwUuid IdUuid => _pwGroup?.Uuid;
|
||||
public string Id => IdUuid?.ToHexString();
|
||||
public bool IsNotRoot => ParentGroup != null;
|
||||
|
||||
public bool ShowRestore => IsNotRoot && ParentGroup.IsSelected;
|
||||
|
||||
public bool IsRecycleOnDelete => _database.IsRecycleBinEnabled && !IsSelected && !ParentGroup.IsSelected;
|
||||
|
||||
/// <summary>
|
||||
/// Is the Group the database Recycle Bin?
|
||||
/// </summary>
|
||||
public bool IsSelected
|
||||
{
|
||||
get => _database != null && _database.IsRecycleBinEnabled && _database.RecycleBin?.Id == Id;
|
||||
set
|
||||
{
|
||||
if (value && _pwGroup != null) _database.RecycleBin = this;
|
||||
}
|
||||
}
|
||||
|
||||
public IOrderedEnumerable<IGrouping<char, EntryVm>> EntriesZoomedOut => from e in Entries
|
||||
group e by e.Name.ToUpper().FirstOrDefault() into grp
|
||||
orderby grp.Key
|
||||
select grp;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get => _pwGroup == null ? string.Empty : _pwGroup.Name;
|
||||
set => _pwGroup.Name = value;
|
||||
}
|
||||
|
||||
public int IconId
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_pwGroup?.IconId != null) return (int) _pwGroup?.IconId;
|
||||
return -1;
|
||||
}
|
||||
set => _pwGroup.IconId = (PwIcon)value;
|
||||
}
|
||||
|
||||
public bool IsEditMode
|
||||
{
|
||||
get => _isEditMode;
|
||||
set
|
||||
{
|
||||
SetProperty(ref _isEditMode, value);
|
||||
((RelayCommand)SortEntriesCommand).RaiseCanExecuteChanged();
|
||||
((RelayCommand)SortGroupsCommand).RaiseCanExecuteChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsMenuClosed
|
||||
{
|
||||
get => _isMenuClosed;
|
||||
set => SetProperty(ref _isMenuClosed, value);
|
||||
}
|
||||
|
||||
public IEnumerable<IPwEntity> BreadCrumb
|
||||
{
|
||||
get
|
||||
{
|
||||
var groups = new Stack<GroupVm>();
|
||||
var group = this;
|
||||
while (group.ParentGroup != null)
|
||||
{
|
||||
group = group.ParentGroup;
|
||||
groups.Push(group);
|
||||
}
|
||||
|
||||
return groups;
|
||||
}
|
||||
}
|
||||
|
||||
public ICommand SaveCommand { get; }
|
||||
public ICommand SortEntriesCommand { get; }
|
||||
public ICommand SortGroupsCommand { get; }
|
||||
public ICommand UndoDeleteCommand { get; }
|
||||
|
||||
private readonly PwGroup _pwGroup;
|
||||
private readonly IDatabaseService _database;
|
||||
private bool _isEditMode;
|
||||
private PwEntry _reorderedEntry;
|
||||
private ObservableCollection<EntryVm> _entries = new ObservableCollection<EntryVm>();
|
||||
private bool _isMenuClosed = true;
|
||||
|
||||
public GroupVm() {}
|
||||
|
||||
internal GroupVm(PwGroup pwGroup, GroupVm parent, PwUuid recycleBinId = null) : this(pwGroup, parent,
|
||||
DatabaseService.Instance, recycleBinId)
|
||||
{ }
|
||||
|
||||
public GroupVm(PwGroup pwGroup, GroupVm parent, IDatabaseService database, PwUuid recycleBinId = null)
|
||||
{
|
||||
_pwGroup = pwGroup;
|
||||
_database = database;
|
||||
ParentGroup = parent;
|
||||
|
||||
SaveCommand = new RelayCommand(() => _database.Save());
|
||||
SortEntriesCommand = new RelayCommand(async () =>
|
||||
await SortEntriesAsync().ConfigureAwait(false), () => IsEditMode);
|
||||
SortGroupsCommand = new RelayCommand(async () =>
|
||||
await SortGroupsAsync().ConfigureAwait(false), () => IsEditMode);
|
||||
UndoDeleteCommand = new RelayCommand(() => Move(PreviousGroup), () => PreviousGroup != null);
|
||||
|
||||
if (recycleBinId != null && _pwGroup.Uuid.Equals(recycleBinId)) _database.RecycleBin = this;
|
||||
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)));
|
||||
}
|
||||
|
||||
private void Entries_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
switch (e.Action)
|
||||
{
|
||||
case NotifyCollectionChangedAction.Remove:
|
||||
var oldIndex = (uint) e.OldStartingIndex;
|
||||
_reorderedEntry = _pwGroup.Entries.GetAt(oldIndex);
|
||||
_pwGroup.Entries.RemoveAt(oldIndex);
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Add:
|
||||
if (_reorderedEntry == null) _pwGroup.AddEntry(((EntryVm) e.NewItems[0]).GetPwEntry(), true);
|
||||
else _pwGroup.Entries.Insert((uint)e.NewStartingIndex, _reorderedEntry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public GroupVm AddNewGroup(string name = "")
|
||||
{
|
||||
var pwGroup = new PwGroup(true, true, name, PwIcon.Folder);
|
||||
_pwGroup.AddGroup(pwGroup, true);
|
||||
var newGroup = new GroupVm(pwGroup, this) {Name = name, IsEditMode = string.IsNullOrEmpty(name)};
|
||||
Groups.Add(newGroup);
|
||||
return newGroup;
|
||||
}
|
||||
|
||||
public EntryVm AddNewEntry()
|
||||
{
|
||||
var pwEntry = new PwEntry(true, true);
|
||||
var newEntry = new EntryVm(pwEntry, this) {IsEditMode = true};
|
||||
newEntry.GeneratePassword();
|
||||
Entries.Add(newEntry);
|
||||
return newEntry;
|
||||
}
|
||||
|
||||
public void MarkForDelete(string recycleBinTitle)
|
||||
{
|
||||
if (_database.IsRecycleBinEnabled && _database.RecycleBin?.IdUuid == null)
|
||||
_database.CreateRecycleBin(recycleBinTitle);
|
||||
Move(_database.IsRecycleBinEnabled && !IsSelected ? _database.RecycleBin : null);
|
||||
((RelayCommand)UndoDeleteCommand).RaiseCanExecuteChanged();
|
||||
}
|
||||
|
||||
public void UndoDelete()
|
||||
{
|
||||
Move(PreviousGroup);
|
||||
}
|
||||
|
||||
public void Move(GroupVm destination)
|
||||
{
|
||||
PreviousGroup = ParentGroup;
|
||||
PreviousGroup.Groups.Remove(this);
|
||||
PreviousGroup._pwGroup.Groups.Remove(_pwGroup);
|
||||
if (destination == null)
|
||||
{
|
||||
_database.AddDeletedItem(IdUuid);
|
||||
return;
|
||||
}
|
||||
ParentGroup = destination;
|
||||
ParentGroup.Groups.Add(this);
|
||||
ParentGroup._pwGroup.AddGroup(_pwGroup, true);
|
||||
}
|
||||
|
||||
public void CommitDelete()
|
||||
{
|
||||
_pwGroup.ParentGroup.Groups.Remove(_pwGroup);
|
||||
if (_database.IsRecycleBinEnabled && !PreviousGroup.IsSelected) _database.RecycleBin._pwGroup.AddGroup(_pwGroup, true);
|
||||
else _database.AddDeletedItem(IdUuid);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
|
||||
private async Task SortEntriesAsync()
|
||||
{
|
||||
var comparer = new PwEntryComparer(PwDefs.TitleField, true, false);
|
||||
try
|
||||
{
|
||||
_pwGroup.Entries.Sort(comparer);
|
||||
Entries = new ObservableCollection<EntryVm>(Entries.OrderBy(e => e.Name));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
await MessageDialogHelper.ShowErrorDialog(e);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SortGroupsAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
_pwGroup.SortSubGroups(false);
|
||||
Groups = new ObservableCollection<GroupVm>(Groups.OrderBy(g => g.Name).ThenBy(g => g._pwGroup == null));
|
||||
OnPropertyChanged("Groups");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
await MessageDialogHelper.ShowErrorDialog(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -1,149 +0,0 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Autofac;
|
||||
using ModernKeePass.Domain.AOP;
|
||||
using ModernKeePass.Domain.Dtos;
|
||||
using ModernKeePass.Domain.Enums;
|
||||
using ModernKeePass.Domain.Interfaces;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
{
|
||||
public class CredentialsViewModel: NotifyPropertyChangedBase
|
||||
{
|
||||
|
||||
private bool _hasPassword;
|
||||
private bool _hasKeyFile;
|
||||
private bool _hasUserAccount;
|
||||
private bool _isOpening;
|
||||
private string _password = string.Empty;
|
||||
private string _status;
|
||||
private CredentialStatusTypes _statusType;
|
||||
private string _keyFilePath = string.Empty;
|
||||
private string _keyFileText;
|
||||
private readonly IResourceService _resourceService;
|
||||
private readonly IDatabaseService _databaseService;
|
||||
|
||||
public bool HasPassword
|
||||
{
|
||||
get => _hasPassword;
|
||||
set
|
||||
{
|
||||
SetProperty(ref _hasPassword, value);
|
||||
OnPropertyChanged(nameof(IsValid));
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasKeyFile
|
||||
{
|
||||
get => _hasKeyFile;
|
||||
set
|
||||
{
|
||||
SetProperty(ref _hasKeyFile, value);
|
||||
OnPropertyChanged(nameof(IsValid));
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasUserAccount
|
||||
{
|
||||
get => _hasUserAccount;
|
||||
set
|
||||
{
|
||||
SetProperty(ref _hasUserAccount, value);
|
||||
OnPropertyChanged(nameof(IsValid));
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsValid => !_isOpening && (HasPassword || HasKeyFile && KeyFilePath != string.Empty || HasUserAccount);
|
||||
|
||||
public string Status
|
||||
{
|
||||
get => _status;
|
||||
set => SetProperty(ref _status, value);
|
||||
}
|
||||
|
||||
public int StatusType
|
||||
{
|
||||
get => (int)_statusType;
|
||||
set => SetProperty(ref _statusType, (CredentialStatusTypes)value);
|
||||
}
|
||||
|
||||
public string Password
|
||||
{
|
||||
get => _password;
|
||||
set
|
||||
{
|
||||
_password = value;
|
||||
StatusType = (int)CredentialStatusTypes.Normal;
|
||||
Status = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public string KeyFilePath
|
||||
{
|
||||
get => _keyFilePath;
|
||||
set
|
||||
{
|
||||
_keyFilePath = value;
|
||||
OnPropertyChanged(nameof(IsValid));
|
||||
}
|
||||
}
|
||||
|
||||
public string KeyFileText
|
||||
{
|
||||
get => _keyFileText;
|
||||
set => SetProperty(ref _keyFileText, value);
|
||||
}
|
||||
|
||||
|
||||
public CredentialsViewModel() : this(App.Container.Resolve<IDatabaseService>(), App.Container.Resolve<IResourceService>()) { }
|
||||
|
||||
public CredentialsViewModel(IDatabaseService databaseService, IResourceService resourceService)
|
||||
{
|
||||
_databaseService = databaseService;
|
||||
_resourceService = resourceService;
|
||||
_keyFileText = _resourceService.GetResourceValue("CompositeKeyDefaultKeyFile");
|
||||
}
|
||||
|
||||
public async Task<bool> OpenDatabase(FileInfo fileInfo)
|
||||
{
|
||||
try
|
||||
{
|
||||
_isOpening = true;
|
||||
OnPropertyChanged(nameof(IsValid));
|
||||
var credentials = new Credentials
|
||||
{
|
||||
KeyFilePath = HasKeyFile ? KeyFilePath : string.Empty,
|
||||
Password = HasPassword ? Password : string.Empty
|
||||
};
|
||||
await Task.Run(() => _databaseService.Open(fileInfo, credentials));
|
||||
return true;
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
var errorMessage = new StringBuilder($"{_resourceService.GetResourceValue("CompositeKeyErrorOpen")}\n");
|
||||
if (HasPassword) errorMessage.AppendLine(_resourceService.GetResourceValue("CompositeKeyErrorUserPassword"));
|
||||
if (HasKeyFile) errorMessage.AppendLine(_resourceService.GetResourceValue("CompositeKeyErrorUserKeyFile"));
|
||||
if (HasUserAccount) errorMessage.AppendLine(_resourceService.GetResourceValue("CompositeKeyErrorUserAccount"));
|
||||
UpdateStatus(errorMessage.ToString(), CredentialStatusTypes.Error);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
var error = $"{_resourceService.GetResourceValue("CompositeKeyErrorOpen")}{e.Message}";
|
||||
UpdateStatus(error, CredentialStatusTypes.Error);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_isOpening = false;
|
||||
OnPropertyChanged(nameof(IsValid));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void UpdateStatus(string text, CredentialStatusTypes type)
|
||||
{
|
||||
Status = text;
|
||||
StatusType = (int)type;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,93 +0,0 @@
|
||||
using Autofac;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using ModernKeePass.Domain.AOP;
|
||||
using ModernKeePass.Domain.Dtos;
|
||||
using ModernKeePass.Domain.Enums;
|
||||
using ModernKeePass.Domain.Interfaces;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
{
|
||||
public class UpdateCredentialsViewModel : NotifyPropertyChangedBase
|
||||
{
|
||||
private readonly ISecurityService _securityService;
|
||||
private bool _hasPassword;
|
||||
private bool _hasKeyFile;
|
||||
private bool _hasUserAccount;
|
||||
private string _confirmPassword;
|
||||
private string _password;
|
||||
private string _keyFileText;
|
||||
private string _status;
|
||||
private CredentialStatusTypes _statusType;
|
||||
|
||||
public string Password
|
||||
{
|
||||
get => _password;
|
||||
set
|
||||
{
|
||||
SetProperty(ref _password, value);
|
||||
OnPropertyChanged(nameof(IsValid));
|
||||
}
|
||||
}
|
||||
|
||||
public string ConfirmPassword
|
||||
{
|
||||
get => _confirmPassword;
|
||||
set => SetProperty(ref _confirmPassword, value);
|
||||
}
|
||||
|
||||
public string KeyFilePath { get; set; }
|
||||
|
||||
public bool HasPassword
|
||||
{
|
||||
get => _hasPassword;
|
||||
set => SetProperty(ref _hasPassword, value);
|
||||
}
|
||||
|
||||
public bool HasKeyFile
|
||||
{
|
||||
get => _hasKeyFile;
|
||||
set => SetProperty(ref _hasKeyFile, value);
|
||||
}
|
||||
|
||||
public bool HasUserAccount
|
||||
{
|
||||
get => _hasUserAccount;
|
||||
set => SetProperty(ref _hasUserAccount, value);
|
||||
}
|
||||
|
||||
public string KeyFileText
|
||||
{
|
||||
get => _keyFileText;
|
||||
set => SetProperty(ref _keyFileText, value);
|
||||
}
|
||||
|
||||
public string Status
|
||||
{
|
||||
get => _status;
|
||||
set => SetProperty(ref _status, value);
|
||||
}
|
||||
|
||||
public int StatusType
|
||||
{
|
||||
get => (int)_statusType;
|
||||
set => SetProperty(ref _statusType, (CredentialStatusTypes)value);
|
||||
}
|
||||
|
||||
public double PasswordComplexityIndicator => _securityService.EstimatePasswordComplexity(Password);
|
||||
|
||||
public bool IsValid => HasPassword && Password == ConfirmPassword || HasKeyFile && KeyFilePath != string.Empty || HasUserAccount;
|
||||
|
||||
public UpdateCredentialsViewModel(): this(App.Container.Resolve<ISecurityService>()) { }
|
||||
|
||||
public UpdateCredentialsViewModel(ISecurityService securityService)
|
||||
{
|
||||
_securityService = securityService;
|
||||
}
|
||||
|
||||
internal Task<bool> CreateDatabase(FileInfo fileInfo)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
@@ -12,8 +12,8 @@
|
||||
<AssemblyName>ModernKeePass</AssemblyName>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
<EnableDotNetNativeCompatibleProfile>true</EnableDotNetNativeCompatibleProfile>
|
||||
<TargetPlatformVersion>10.0.18362.0</TargetPlatformVersion>
|
||||
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
||||
<TargetPlatformVersion>10.0.14393.0</TargetPlatformVersion>
|
||||
<TargetPlatformMinVersion>10.0.14393.0</TargetPlatformMinVersion>
|
||||
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
@@ -97,7 +97,6 @@
|
||||
<Compile Include="App.xaml.cs">
|
||||
<DependentUpon>App.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="ViewModels\UserControls\UpdateCredentialsViewModel.cs" />
|
||||
<Compile Include="Views\UserControls\UpdateCredentialsUserControl.xaml.cs">
|
||||
<DependentUpon>UpdateCredentialsUserControl.xaml</DependentUpon>
|
||||
</Compile>
|
||||
@@ -108,7 +107,6 @@
|
||||
<Compile Include="ViewModels\ListItems\EntryItemViewModel.cs" />
|
||||
<Compile Include="ViewModels\GroupsViewModel.cs" />
|
||||
<Compile Include="ViewModels\ListItems\GroupItemViewModel.cs" />
|
||||
<Compile Include="ViewModels\ListItems\SettingsSaveViewModel.cs" />
|
||||
<Compile Include="ViewModels\SettingsViewModel.cs" />
|
||||
<Compile Include="Views\EntriesPage.xaml.cs">
|
||||
<DependentUpon>EntriesPage.xaml</DependentUpon>
|
||||
@@ -171,10 +169,6 @@
|
||||
<Compile Include="Views\MainPageFrames\WelcomePage.xaml.cs">
|
||||
<DependentUpon>WelcomePage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="ViewModels\UserControls\CredentialsViewModel.cs" />
|
||||
<Compile Include="ViewModels\ListItems\ListMenuItemViewModel.cs" />
|
||||
<Compile Include="ViewModels\ListItems\MainMenuItemViewModel.cs" />
|
||||
<Compile Include="ViewModels\ListItems\RecentItemViewModel.cs" />
|
||||
<Content Include="Views\Old\EntryDetailPage.xaml.cs">
|
||||
<DependentUpon>EntryDetailPage.xaml</DependentUpon>
|
||||
</Content>
|
||||
@@ -191,14 +185,10 @@
|
||||
<DependentUpon>SaveDatabasePage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Content Include="ViewModels\Old\EntryVm.cs" />
|
||||
<Content Include="ViewModels\Old\GroupVm.cs" />
|
||||
<Compile Include="ViewModels\ListItems\SettingsNewViewModel.cs" />
|
||||
<Compile Include="ViewModels\NewViewModel.cs" />
|
||||
<Compile Include="ViewModels\OpenViewModel.cs" />
|
||||
<Compile Include="ViewModels\RecentViewModel.cs" />
|
||||
<Compile Include="ViewModels\SaveViewModel.cs" />
|
||||
<Compile Include="ViewModels\ListItems\SettingsDatabaseViewModel.cs" />
|
||||
<Compile Include="Views\UserControls\HamburgerMenuUserControl.xaml.cs">
|
||||
<DependentUpon>HamburgerMenuUserControl.xaml</DependentUpon>
|
||||
</Compile>
|
||||
@@ -451,9 +441,6 @@
|
||||
<Content Include="Assets\Wide310x150Logo.scale-80.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Autofac">
|
||||
<Version>5.1.2</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.AppCenter.Analytics">
|
||||
<Version>3.0.0</Version>
|
||||
</PackageReference>
|
||||
|
@@ -10,6 +10,8 @@
|
||||
public class Settings
|
||||
{
|
||||
public static string SaveSuspend => nameof(SaveSuspend);
|
||||
public static string Sample => nameof(Sample);
|
||||
public static string DefaultFileFormat => nameof(DefaultFileFormat);
|
||||
}
|
||||
}
|
||||
}
|
@@ -3,7 +3,7 @@ using Windows.UI.Xaml.Controls;
|
||||
using ModernKeePass.Domain.AOP;
|
||||
using ModernKeePass.Domain.Interfaces;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
namespace ModernKeePass.ViewModels.ListItems
|
||||
{
|
||||
public class ListMenuItemVm : NotifyPropertyChangedBase, IIsEnabled, ISelectableModel
|
||||
{
|
@@ -1,6 +1,6 @@
|
||||
using Windows.UI.Xaml.Controls;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
namespace ModernKeePass.ViewModels.ListItems
|
||||
{
|
||||
public class MainMenuItemVm: ListMenuItemVm
|
||||
{
|
@@ -4,7 +4,7 @@ using ModernKeePass.Domain.AOP;
|
||||
using ModernKeePass.Domain.Dtos;
|
||||
using ModernKeePass.Domain.Interfaces;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
namespace ModernKeePass.ViewModels.ListItems
|
||||
{
|
||||
public class RecentItemVm: NotifyPropertyChangedBase, ISelectableModel
|
||||
{
|
@@ -18,7 +18,7 @@ using ModernKeePass.Application.Parameters.Queries.GetCompressions;
|
||||
using ModernKeePass.Application.Parameters.Queries.GetKeyDerivations;
|
||||
using ModernKeePass.Domain.AOP;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
namespace ModernKeePass.ViewModels.ListItems
|
||||
{
|
||||
// TODO: implement Kdf settings
|
||||
public class SettingsDatabaseVm: NotifyPropertyChangedBase
|
@@ -1,8 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using ModernKeePass.Application.Common.Interfaces;
|
||||
using ModernKeePass.Common;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
namespace ModernKeePass.ViewModels.ListItems
|
||||
{
|
||||
public class SettingsNewVm
|
||||
{
|
||||
@@ -18,16 +19,16 @@ namespace ModernKeePass.ViewModels
|
||||
|
||||
public bool IsCreateSample
|
||||
{
|
||||
get { return _settings.GetSetting<bool>("Sample"); }
|
||||
set { _settings.PutSetting("Sample", value); }
|
||||
get { return _settings.GetSetting<bool>(Constants.Settings.Sample); }
|
||||
set { _settings.PutSetting(Constants.Settings.Sample, value); }
|
||||
}
|
||||
|
||||
public IEnumerable<string> FileFormats => new []{"2", "4"};
|
||||
|
||||
public string FileFormatVersion
|
||||
{
|
||||
get { return _settings.GetSetting<string>("DefaultFileFormat"); }
|
||||
set { _settings.PutSetting("DefaultFileFormat", value); }
|
||||
get { return _settings.GetSetting<string>(Constants.Settings.DefaultFileFormat); }
|
||||
set { _settings.PutSetting(Constants.Settings.DefaultFileFormat, value); }
|
||||
}
|
||||
}
|
||||
}
|
@@ -2,7 +2,7 @@ using Microsoft.Extensions.DependencyInjection;
|
||||
using ModernKeePass.Application.Common.Interfaces;
|
||||
using ModernKeePass.Common;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
namespace ModernKeePass.ViewModels.ListItems
|
||||
{
|
||||
public class SettingsSaveVm
|
||||
{
|
175
WinAppCommon/ViewModels/UserControls/CredentialsViewModel.cs
Normal file
175
WinAppCommon/ViewModels/UserControls/CredentialsViewModel.cs
Normal file
@@ -0,0 +1,175 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using MediatR;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using ModernKeePass.Application.Common.Interfaces;
|
||||
using ModernKeePass.Application.Database.Commands.CreateDatabase;
|
||||
using ModernKeePass.Application.Database.Commands.UpdateCredentials;
|
||||
using ModernKeePass.Application.Database.Queries.GetDatabase;
|
||||
using ModernKeePass.Application.Database.Queries.OpenDatabase;
|
||||
using ModernKeePass.Application.Security.Commands.GenerateKeyFile;
|
||||
using ModernKeePass.Application.Security.Queries.EstimatePasswordComplexity;
|
||||
using ModernKeePass.Domain.AOP;
|
||||
using ModernKeePass.Domain.Dtos;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
{
|
||||
public class CompositeKeyVm : NotifyPropertyChangedBase
|
||||
{
|
||||
public enum StatusTypes
|
||||
{
|
||||
Normal = 0,
|
||||
Error = 1,
|
||||
Warning = 3,
|
||||
Success = 5
|
||||
}
|
||||
|
||||
public bool HasPassword
|
||||
{
|
||||
get { return _hasPassword; }
|
||||
set
|
||||
{
|
||||
SetProperty(ref _hasPassword, value);
|
||||
OnPropertyChanged(nameof(IsValid));
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasKeyFile
|
||||
{
|
||||
get { return _hasKeyFile; }
|
||||
set
|
||||
{
|
||||
SetProperty(ref _hasKeyFile, value);
|
||||
OnPropertyChanged(nameof(IsValid));
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsValid => !_isOpening && (HasPassword || HasKeyFile && KeyFilePath != null);
|
||||
|
||||
public string Status
|
||||
{
|
||||
get { return _status; }
|
||||
set { SetProperty(ref _status, value); }
|
||||
}
|
||||
|
||||
public int StatusType
|
||||
{
|
||||
get { return (int)_statusType; }
|
||||
set { SetProperty(ref _statusType, (StatusTypes)value); }
|
||||
}
|
||||
|
||||
public string Password
|
||||
{
|
||||
get { return _password; }
|
||||
set
|
||||
{
|
||||
_password = value;
|
||||
OnPropertyChanged(nameof(PasswordComplexityIndicator));
|
||||
StatusType = (int)StatusTypes.Normal;
|
||||
Status = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public string KeyFilePath
|
||||
{
|
||||
get { return _keyFilePath; }
|
||||
set
|
||||
{
|
||||
_keyFilePath = value;
|
||||
OnPropertyChanged(nameof(IsValid));
|
||||
}
|
||||
}
|
||||
|
||||
public string KeyFileText
|
||||
{
|
||||
get { return _keyFileText; }
|
||||
set { SetProperty(ref _keyFileText, value); }
|
||||
}
|
||||
|
||||
public string RootGroupId { get; set; }
|
||||
|
||||
public double PasswordComplexityIndicator => _mediator.Send(new EstimatePasswordComplexityQuery { Password = Password }).GetAwaiter().GetResult();
|
||||
|
||||
private bool _hasPassword;
|
||||
private bool _hasKeyFile;
|
||||
private bool _isOpening;
|
||||
private string _password = string.Empty;
|
||||
private string _status;
|
||||
private StatusTypes _statusType;
|
||||
private string _keyFilePath;
|
||||
private string _keyFileText;
|
||||
private readonly IMediator _mediator;
|
||||
private readonly ISettingsProxy _settings;
|
||||
private readonly IResourceProxy _resource;
|
||||
|
||||
public CompositeKeyVm() : this(
|
||||
App.Services.GetRequiredService<IMediator>(),
|
||||
App.Services.GetRequiredService<ISettingsProxy>(),
|
||||
App.Services.GetRequiredService<IResourceProxy>())
|
||||
{ }
|
||||
|
||||
public CompositeKeyVm(IMediator mediator, ISettingsProxy settings, IResourceProxy resource)
|
||||
{
|
||||
_mediator = mediator;
|
||||
_settings = settings;
|
||||
_resource = resource;
|
||||
_keyFileText = _resource.GetResourceValue("CompositeKeyDefaultKeyFile");
|
||||
}
|
||||
|
||||
public async Task<bool> OpenDatabase(string databaseFilePath, bool createNew)
|
||||
{
|
||||
try
|
||||
{
|
||||
_isOpening = true;
|
||||
OnPropertyChanged(nameof(IsValid));
|
||||
if (createNew)
|
||||
{
|
||||
await _mediator.Send(new CreateDatabaseCommand
|
||||
{
|
||||
FilePath = databaseFilePath,
|
||||
KeyFilePath = HasKeyFile ? KeyFilePath : null,
|
||||
Password = HasPassword ? Password : null,
|
||||
Name = "New Database",
|
||||
CreateSampleData = _settings.GetSetting<bool>("Sample")
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
await _mediator.Send(new OpenDatabaseQuery
|
||||
{
|
||||
FilePath = databaseFilePath,
|
||||
KeyFilePath = HasKeyFile ? KeyFilePath : null,
|
||||
Password = HasPassword ? Password : null,
|
||||
});
|
||||
}
|
||||
RootGroupId = (await _mediator.Send(new GetDatabaseQuery())).RootGroupId;
|
||||
return true;
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
var errorMessage = new StringBuilder($"{_resource.GetResourceValue("CompositeKeyErrorOpen")}\n");
|
||||
if (HasPassword) errorMessage.AppendLine(_resource.GetResourceValue("CompositeKeyErrorUserPassword"));
|
||||
if (HasKeyFile) errorMessage.AppendLine(_resource.GetResourceValue("CompositeKeyErrorUserKeyFile"));
|
||||
UpdateStatus(errorMessage.ToString(), StatusTypes.Error);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
var error = $"{_resource.GetResourceValue("CompositeKeyErrorOpen")}{e.Message}";
|
||||
UpdateStatus(error, StatusTypes.Error);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_isOpening = false;
|
||||
OnPropertyChanged(nameof(IsValid));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void UpdateStatus(string text, StatusTypes type)
|
||||
{
|
||||
Status = text;
|
||||
StatusType = (int)type;
|
||||
}
|
||||
}
|
||||
}
|
153
WinAppCommon/ViewModels/UserControls/OpenDatabaseControlVm.cs
Normal file
153
WinAppCommon/ViewModels/UserControls/OpenDatabaseControlVm.cs
Normal file
@@ -0,0 +1,153 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using MediatR;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using ModernKeePass.Application.Common.Interfaces;
|
||||
using ModernKeePass.Application.Database.Queries.GetDatabase;
|
||||
using ModernKeePass.Application.Database.Queries.OpenDatabase;
|
||||
using ModernKeePass.Common;
|
||||
using ModernKeePass.Domain.AOP;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
{
|
||||
public class OpenDatabaseControlVm : NotifyPropertyChangedBase
|
||||
{
|
||||
public enum StatusTypes
|
||||
{
|
||||
Normal = 0,
|
||||
Error = 1,
|
||||
Warning = 3,
|
||||
Success = 5
|
||||
}
|
||||
|
||||
public bool HasPassword
|
||||
{
|
||||
get { return _hasPassword; }
|
||||
set
|
||||
{
|
||||
SetProperty(ref _hasPassword, value);
|
||||
OnPropertyChanged(nameof(IsValid));
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasKeyFile
|
||||
{
|
||||
get { return _hasKeyFile; }
|
||||
set
|
||||
{
|
||||
SetProperty(ref _hasKeyFile, value);
|
||||
OnPropertyChanged(nameof(IsValid));
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsValid => !_isOpening && (HasPassword || HasKeyFile && KeyFilePath != null);
|
||||
|
||||
public string Status
|
||||
{
|
||||
get { return _status; }
|
||||
set { SetProperty(ref _status, value); }
|
||||
}
|
||||
|
||||
public int StatusType
|
||||
{
|
||||
get { return (int)_statusType; }
|
||||
set { SetProperty(ref _statusType, (StatusTypes)value); }
|
||||
}
|
||||
|
||||
public string Password
|
||||
{
|
||||
get { return _password; }
|
||||
set
|
||||
{
|
||||
_password = value;
|
||||
StatusType = (int)StatusTypes.Normal;
|
||||
Status = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public string KeyFilePath
|
||||
{
|
||||
get { return _keyFilePath; }
|
||||
set
|
||||
{
|
||||
_keyFilePath = value;
|
||||
OnPropertyChanged(nameof(IsValid));
|
||||
}
|
||||
}
|
||||
|
||||
public string KeyFileText
|
||||
{
|
||||
get { return _keyFileText; }
|
||||
set { SetProperty(ref _keyFileText, value); }
|
||||
}
|
||||
|
||||
public string RootGroupId { get; set; }
|
||||
|
||||
protected readonly IMediator Mediator;
|
||||
private readonly IResourceProxy _resource;
|
||||
private bool _hasPassword;
|
||||
private bool _hasKeyFile;
|
||||
private bool _isOpening;
|
||||
private string _password = string.Empty;
|
||||
private string _status;
|
||||
private StatusTypes _statusType;
|
||||
private string _keyFilePath;
|
||||
private string _keyFileText;
|
||||
|
||||
|
||||
|
||||
public OpenDatabaseControlVm() : this(
|
||||
App.Services.GetRequiredService<IMediator>(),
|
||||
App.Services.GetRequiredService<IResourceProxy>())
|
||||
{ }
|
||||
|
||||
public OpenDatabaseControlVm(IMediator mediator, IResourceProxy resource)
|
||||
{
|
||||
Mediator = mediator;
|
||||
_resource = resource;
|
||||
_keyFileText = _resource.GetResourceValue("CompositeKeyDefaultKeyFile");
|
||||
}
|
||||
|
||||
public async Task<bool> OpenDatabase(string databaseFilePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
_isOpening = true;
|
||||
OnPropertyChanged(nameof(IsValid));
|
||||
await Mediator.Send(new OpenDatabaseQuery
|
||||
{
|
||||
FilePath = databaseFilePath,
|
||||
KeyFilePath = HasKeyFile ? KeyFilePath : null,
|
||||
Password = HasPassword ? Password : null,
|
||||
});
|
||||
RootGroupId = (await Mediator.Send(new GetDatabaseQuery())).RootGroupId;
|
||||
return true;
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
var errorMessage = new StringBuilder($"{_resource.GetResourceValue("CompositeKeyErrorOpen")}\n");
|
||||
if (HasPassword) errorMessage.AppendLine(_resource.GetResourceValue("CompositeKeyErrorUserPassword"));
|
||||
if (HasKeyFile) errorMessage.AppendLine(_resource.GetResourceValue("CompositeKeyErrorUserKeyFile"));
|
||||
UpdateStatus(errorMessage.ToString(), StatusTypes.Error);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
var error = $"{_resource.GetResourceValue("CompositeKeyErrorOpen")}{e.Message}";
|
||||
UpdateStatus(error, StatusTypes.Error);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_isOpening = false;
|
||||
OnPropertyChanged(nameof(IsValid));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void UpdateStatus(string text, StatusTypes type)
|
||||
{
|
||||
Status = text;
|
||||
StatusType = (int)type;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,47 @@
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using ModernKeePass.Application.Common.Interfaces;
|
||||
using ModernKeePass.Application.Database.Commands.CreateDatabase;
|
||||
using ModernKeePass.Common;
|
||||
using ModernKeePass.Domain.Dtos;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
{
|
||||
public class UpdateCredentialsViewModel : OpenDatabaseControlVm
|
||||
{
|
||||
private readonly ICredentialsProxy _credentials;
|
||||
private readonly ISettingsProxy _settings;
|
||||
private string _confirmPassword;
|
||||
|
||||
|
||||
public string ConfirmPassword
|
||||
{
|
||||
get { return _confirmPassword; }
|
||||
set { SetProperty(ref _confirmPassword, value); }
|
||||
}
|
||||
|
||||
public double PasswordComplexityIndicator => _credentials.EstimatePasswordComplexity(Password);
|
||||
|
||||
public new bool IsValid => HasPassword && Password == ConfirmPassword || HasKeyFile && KeyFilePath != string.Empty;
|
||||
|
||||
public UpdateCredentialsViewModel(): this(App.Services.GetRequiredService<ICredentialsProxy>(), App.Services.GetRequiredService<ISettingsProxy>()) { }
|
||||
|
||||
public UpdateCredentialsViewModel(ICredentialsProxy credentials, ISettingsProxy settings)
|
||||
{
|
||||
_credentials = credentials;
|
||||
_settings = settings;
|
||||
}
|
||||
|
||||
public async Task CreateDatabase(FileInfo fileInfo)
|
||||
{
|
||||
await Mediator.Send(new CreateDatabaseCommand
|
||||
{
|
||||
FilePath = fileInfo.Path,
|
||||
KeyFilePath = HasKeyFile ? KeyFilePath : null,
|
||||
Password = HasPassword ? Password : null,
|
||||
Name = "New Database",
|
||||
CreateSampleData = _settings.GetSetting<bool>(Constants.Settings.Sample)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@@ -38,5 +38,13 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Extensions\DispatcherTaskExtensions.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)TemplateSelectors\FirstItemDataTemplateSelector.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)TemplateSelectors\SelectableDataTemplateSelector.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\Items\ListMenuItemVm.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\Items\MainMenuItemVm.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\Items\RecentItemVm.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\Items\SettingsDatabaseVm.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\Items\SettingsNewVm.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\Items\SettingsSaveVm.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\UserControls\OpenDatabaseControlVm.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\UserControls\UpdateCredentialsViewModel.cs" />
|
||||
</ItemGroup>
|
||||
</Project>
|
Reference in New Issue
Block a user