mirror of
https://github.com/wismna/ModernKeePass.git
synced 2025-10-03 15:40:18 -04:00
Display a big database size warning
Auto rename additional field when it matches standard Treated all fields as new Field class Added the Is Protected property
This commit is contained in:
@@ -94,6 +94,7 @@
|
||||
<Compile Include="Entry\Commands\DeleteField\DeleteFieldCommand.cs" />
|
||||
<Compile Include="Entry\Commands\DeleteHistory\DeleteHistoryCommand.cs" />
|
||||
<Compile Include="Entry\Commands\RestoreHistory\RestoreHistoryCommand.cs" />
|
||||
<Compile Include="Entry\Models\FieldVm.cs" />
|
||||
<Compile Include="Entry\Queries\GetEntry\GetEntryQuery.cs" />
|
||||
<Compile Include="Group\Commands\DeleteEntry\DeleteEntryCommand.cs" />
|
||||
<Compile Include="Group\Commands\DeleteGroup\DeleteGroupCommand.cs" />
|
||||
|
@@ -33,7 +33,7 @@ namespace ModernKeePass.Application.Common.Interfaces
|
||||
EntryEntity GetEntry(string id);
|
||||
Task AddEntry(string parentGroupId, string entryId);
|
||||
Task MoveEntry(string parentGroupId, string entryId, int index);
|
||||
void UpdateEntry(string entryId, string fieldName, object fieldValue);
|
||||
void UpdateEntry(string entryId, string fieldName, object fieldValue, bool isProtected);
|
||||
void DeleteField(string entryId, string fieldName);
|
||||
Task RemoveEntry(string parentGroupId, string entryId);
|
||||
EntryEntity CreateEntry(string parentGroupId);
|
||||
|
@@ -5,7 +5,6 @@ namespace ModernKeePass.Application.Common.Interfaces
|
||||
public interface IEntityVm
|
||||
{
|
||||
string Id { get; set; }
|
||||
string Title { get; set; }
|
||||
Icon Icon { get; set; }
|
||||
string ParentGroupId { get; set; }
|
||||
string ParentGroupName { get; set; }
|
||||
|
@@ -64,17 +64,17 @@ namespace ModernKeePass.Application.Database.Commands.CreateDatabase
|
||||
_database.UpdateGroup(internetGroup);
|
||||
|
||||
var sample1 = _database.CreateEntry(_database.RootGroupId);
|
||||
_database.UpdateEntry(sample1.Id, EntryFieldName.Title, "Sample Entry" );
|
||||
_database.UpdateEntry(sample1.Id, EntryFieldName.UserName, "Username" );
|
||||
_database.UpdateEntry(sample1.Id, EntryFieldName.Password, "Password" );
|
||||
_database.UpdateEntry(sample1.Id, EntryFieldName.Url, "https://keepass.info/" );
|
||||
_database.UpdateEntry(sample1.Id, EntryFieldName.Notes, "You may safely delete this sample" );
|
||||
_database.UpdateEntry(sample1.Id, EntryFieldName.Title, "Sample Entry", true);
|
||||
_database.UpdateEntry(sample1.Id, EntryFieldName.UserName, "Username", true);
|
||||
_database.UpdateEntry(sample1.Id, EntryFieldName.Password, "Password", true);
|
||||
_database.UpdateEntry(sample1.Id, EntryFieldName.Url, "https://keepass.info/", true);
|
||||
_database.UpdateEntry(sample1.Id, EntryFieldName.Notes, "You may safely delete this sample", true);
|
||||
|
||||
var sample2 = _database.CreateEntry(_database.RootGroupId);
|
||||
_database.UpdateEntry(sample2.Id, EntryFieldName.Title, "Sample Entry #2" );
|
||||
_database.UpdateEntry(sample2.Id, EntryFieldName.UserName, "Michael321" );
|
||||
_database.UpdateEntry(sample2.Id, EntryFieldName.Password, "12345" );
|
||||
_database.UpdateEntry(sample2.Id, EntryFieldName.Url, "https://keepass.info/help/kb/testform.html" );
|
||||
_database.UpdateEntry(sample2.Id, EntryFieldName.Title, "Sample Entry #2", true);
|
||||
_database.UpdateEntry(sample2.Id, EntryFieldName.UserName, "Michael321", true);
|
||||
_database.UpdateEntry(sample2.Id, EntryFieldName.Password, "12345", true);
|
||||
_database.UpdateEntry(sample2.Id, EntryFieldName.Url, "https://keepass.info/help/kb/testform.html", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -9,6 +9,7 @@ namespace ModernKeePass.Application.Entry.Commands.UpsertField
|
||||
public string EntryId { get; set; }
|
||||
public string FieldName { get; set; }
|
||||
public object FieldValue { get; set; }
|
||||
public bool IsProtected { get; set; } = true;
|
||||
|
||||
public class UpsertFieldCommandHandler : IRequestHandler<UpsertFieldCommand>
|
||||
{
|
||||
@@ -23,7 +24,7 @@ namespace ModernKeePass.Application.Entry.Commands.UpsertField
|
||||
{
|
||||
if (!_database.IsOpen) throw new DatabaseClosedException();
|
||||
|
||||
_database.UpdateEntry(message.EntryId, message.FieldName, message.FieldValue);
|
||||
_database.UpdateEntry(message.EntryId, message.FieldName, message.FieldValue, message.IsProtected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -15,13 +15,13 @@ namespace ModernKeePass.Application.Entry.Models
|
||||
public string ParentGroupId { get; set; }
|
||||
public string ParentGroupName { get; set; }
|
||||
public string Id { get; set; }
|
||||
public string Title { get; set; }
|
||||
public string Username { get; set; }
|
||||
public string Password { get; set; }
|
||||
public string Notes { get; set; }
|
||||
public string Url { get; set; }
|
||||
public bool HasUrl => !string.IsNullOrEmpty(Url);
|
||||
public Dictionary<string, string> AdditionalFields { get; set; }
|
||||
public FieldVm Title { get; set; }
|
||||
public FieldVm Username { get; set; }
|
||||
public FieldVm Password { get; set; }
|
||||
public FieldVm Notes { get; set; }
|
||||
public FieldVm Url { get; set; }
|
||||
public bool HasUrl => !string.IsNullOrEmpty(Url.Value);
|
||||
public List<FieldVm> AdditionalFields { get; set; }
|
||||
public List<EntryVm> History { get; set; }
|
||||
public Icon Icon { get; set; }
|
||||
public Color ForegroundColor { get; set; }
|
||||
@@ -42,12 +42,18 @@ namespace ModernKeePass.Application.Entry.Models
|
||||
.ForMember(d => d.ParentGroupId, opts => opts.MapFrom(s => s.ParentId))
|
||||
.ForMember(d => d.ParentGroupName, opts => opts.MapFrom(s => s.ParentName))
|
||||
.ForMember(d => d.Id, opts => opts.MapFrom(s => s.Id))
|
||||
.ForMember(d => d.Title, opts => opts.MapFrom(s => s.Name))
|
||||
.ForMember(d => d.Username, opts => opts.MapFrom(s => s.UserName))
|
||||
.ForMember(d => d.Password, opts => opts.MapFrom(s => s.Password))
|
||||
.ForMember(d => d.Url, opts => opts.MapFrom(s => s.Url))
|
||||
.ForMember(d => d.Notes, opts => opts.MapFrom(s => s.Notes))
|
||||
.ForMember(d => d.AdditionalFields, opts => opts.MapFrom(s => s.AdditionalFields))
|
||||
.ForMember(d => d.Title, opts => opts.MapFrom(s => s.Fields.FirstOrDefault(f =>
|
||||
f.Name.Equals(EntryFieldName.Title, StringComparison.OrdinalIgnoreCase)) ?? new FieldEntity { Name = EntryFieldName.Title, IsProtected = true } ))
|
||||
.ForMember(d => d.Username, opts => opts.MapFrom(s => s.Fields.FirstOrDefault(f =>
|
||||
f.Name.Equals(EntryFieldName.UserName, StringComparison.OrdinalIgnoreCase)) ?? new FieldEntity { Name = EntryFieldName.UserName, IsProtected = true } ))
|
||||
.ForMember(d => d.Password, opts => opts.MapFrom(s => s.Fields.FirstOrDefault(f =>
|
||||
f.Name.Equals(EntryFieldName.Password, StringComparison.OrdinalIgnoreCase)) ?? new FieldEntity { Name = EntryFieldName.Password, IsProtected = true } ))
|
||||
.ForMember(d => d.Url, opts => opts.MapFrom(s => s.Fields.FirstOrDefault(f =>
|
||||
f.Name.Equals(EntryFieldName.Url, StringComparison.OrdinalIgnoreCase)) ?? new FieldEntity { Name = EntryFieldName.Url, IsProtected = true } ))
|
||||
.ForMember(d => d.Notes, opts => opts.MapFrom(s => s.Fields.FirstOrDefault(f =>
|
||||
f.Name.Equals(EntryFieldName.Notes, StringComparison.OrdinalIgnoreCase)) ?? new FieldEntity { Name = EntryFieldName.Notes, IsProtected = true } ))
|
||||
.ForMember(d => d.AdditionalFields, opts => opts.MapFrom(s =>
|
||||
s.Fields.Where(f => !EntryFieldName.StandardFieldNames.Contains(f.Name, StringComparer.OrdinalIgnoreCase))))
|
||||
.ForMember(d => d.History, opts => opts.MapFrom(s => s.History.Reverse()))
|
||||
.ForMember(d => d.HasExpirationDate, opts => opts.MapFrom(s => s.HasExpirationDate))
|
||||
.ForMember(d => d.ExpirationDate, opts => opts.MapFrom(s => s.ExpirationDate))
|
||||
|
20
ModernKeePass.Application/Entry/Models/FieldVm.cs
Normal file
20
ModernKeePass.Application/Entry/Models/FieldVm.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using AutoMapper;
|
||||
using ModernKeePass.Application.Common.Mappings;
|
||||
using ModernKeePass.Domain.Entities;
|
||||
|
||||
namespace ModernKeePass.Application.Entry.Models
|
||||
{
|
||||
public class FieldVm: IMapFrom<FieldEntity>
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Value { get; set; }
|
||||
public bool IsProtected { get; set; }
|
||||
|
||||
public override string ToString() => Value;
|
||||
|
||||
public void Mapping(Profile profile)
|
||||
{
|
||||
profile.CreateMap<FieldEntity, FieldVm>();
|
||||
}
|
||||
}
|
||||
}
|
@@ -24,7 +24,7 @@ namespace ModernKeePass.Application.Group.Commands.SortEntries
|
||||
if (!_database.IsOpen) throw new DatabaseClosedException();
|
||||
|
||||
_database.SortEntries(message.Group.Id);
|
||||
message.Group.Entries = message.Group.Entries.OrderBy(e => e.Title).ToList();
|
||||
message.Group.Entries = message.Group.Entries.OrderBy(e => e.Title.Value).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -82,6 +82,7 @@
|
||||
<Compile Include="Dtos\PasswordGenerationOptions.cs" />
|
||||
<Compile Include="Entities\BaseEntity.cs" />
|
||||
<Compile Include="Entities\EntryEntity.cs" />
|
||||
<Compile Include="Entities\FieldEntity.cs" />
|
||||
<Compile Include="Entities\GroupEntity.cs" />
|
||||
<Compile Include="Enums\CredentialStatusTypes.cs" />
|
||||
<Compile Include="Enums\DatabaseVersion.cs" />
|
||||
|
@@ -7,17 +7,13 @@ namespace ModernKeePass.Domain.Entities
|
||||
{
|
||||
public class EntryEntity: BaseEntity
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public string Password { 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>();
|
||||
public IEnumerable<FieldEntity> Fields { get; set; } = new List<FieldEntity>();
|
||||
public IEnumerable<EntryEntity> History { get; set; } = new List<EntryEntity>();
|
||||
public Dictionary<string, byte[]> Attachments { get; set; } = new Dictionary<string, byte[]>();
|
||||
public DateTimeOffset ExpirationDate { get; set; }
|
||||
public Icon Icon { get; set; }
|
||||
public Color ForegroundColor { get; set; }
|
||||
public Color BackgroundColor { get; set; }
|
||||
public bool HasExpirationDate { get; set; }
|
||||
public Dictionary<string, byte[]> Attachments { get; set; } = new Dictionary<string, byte[]>();
|
||||
}
|
||||
}
|
9
ModernKeePass.Domain/Entities/FieldEntity.cs
Normal file
9
ModernKeePass.Domain/Entities/FieldEntity.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace ModernKeePass.Domain.Entities
|
||||
{
|
||||
public class FieldEntity
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Value { get; set; }
|
||||
public bool IsProtected { get; set; }
|
||||
}
|
||||
}
|
@@ -1,4 +1,6 @@
|
||||
namespace ModernKeePass.Domain.Enums
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ModernKeePass.Domain.Enums
|
||||
{
|
||||
public static class EntryFieldName
|
||||
{
|
||||
@@ -12,5 +14,19 @@
|
||||
public const string HasExpirationDate = nameof(HasExpirationDate);
|
||||
public const string BackgroundColor = nameof(BackgroundColor);
|
||||
public const string ForegroundColor = nameof(ForegroundColor);
|
||||
|
||||
public static IEnumerable<string> StandardFieldNames = new[]
|
||||
{
|
||||
Title,
|
||||
UserName,
|
||||
Password,
|
||||
Url,
|
||||
Notes,
|
||||
Icon,
|
||||
ExpirationDate,
|
||||
HasExpirationDate,
|
||||
BackgroundColor,
|
||||
ForegroundColor
|
||||
};
|
||||
}
|
||||
}
|
@@ -80,8 +80,7 @@
|
||||
<Compile Include="DependencyInjection.cs" />
|
||||
<Compile Include="File\CsvImportFormat.cs" />
|
||||
<Compile Include="KeePass\EntryFieldMapper.cs" />
|
||||
<Compile Include="KeePass\EntryMappingProfile.cs" />
|
||||
<Compile Include="KeePass\GroupMappingProfile.cs" />
|
||||
<Compile Include="KeePass\MappingProfiles.cs" />
|
||||
<Compile Include="KeePass\IconMapper.cs" />
|
||||
<Compile Include="KeePass\KeePassCryptographyClient.cs" />
|
||||
<Compile Include="KeePass\KeePassDatabaseClient.cs" />
|
||||
|
@@ -1,23 +0,0 @@
|
||||
using AutoMapper;
|
||||
using ModernKeePass.Domain.Entities;
|
||||
using ModernKeePassLib;
|
||||
|
||||
namespace ModernKeePass.Infrastructure.KeePass
|
||||
{
|
||||
public class GroupMappingProfile : Profile
|
||||
{
|
||||
public GroupMappingProfile()
|
||||
{
|
||||
CreateMap<PwGroup, GroupEntity>()
|
||||
.ForMember(d => d.ParentId, opts => opts.MapFrom(s => s.ParentGroup.Uuid.ToHexString()))
|
||||
.ForMember(d => d.ParentName, opts => opts.MapFrom(s => s.ParentGroup.Name))
|
||||
.ForMember(d => d.Id, opts => opts.MapFrom(s => s.Uuid.ToHexString()))
|
||||
.ForMember(d => d.Name, opts => opts.MapFrom(s => s.Name))
|
||||
.ForMember(d => d.Icon, opts => opts.MapFrom(s => IconMapper.MapPwIconToIcon(s.IconId)))
|
||||
.ForMember(d => d.LastModificationDate, opts => opts.MapFrom(s => s.LastModificationTime))
|
||||
.ForMember(d => d.Entries, opts => opts.MapFrom(s => s.Entries))
|
||||
.ForMember(d => d.SubGroups, opts => opts.MapFrom(s => s.Groups))
|
||||
.MaxDepth(2);
|
||||
}
|
||||
}
|
||||
}
|
@@ -228,7 +228,7 @@ namespace ModernKeePass.Infrastructure.KeePass
|
||||
_pwDatabase.DeletedObjects.Add(new PwDeletedObject(BuildIdFromString(entityId), _dateTime.Now));
|
||||
}
|
||||
|
||||
public void UpdateEntry(string entryId, string fieldName, object fieldValue)
|
||||
public void UpdateEntry(string entryId, string fieldName, object fieldValue, bool isProtected)
|
||||
{
|
||||
var pwEntry = _pwDatabase.RootGroup.FindEntry(BuildIdFromString(entryId), true);
|
||||
|
||||
@@ -239,7 +239,7 @@ namespace ModernKeePass.Infrastructure.KeePass
|
||||
case EntryFieldName.Password:
|
||||
case EntryFieldName.Notes:
|
||||
case EntryFieldName.Url:
|
||||
pwEntry.Strings.Set(EntryFieldMapper.MapFieldToPwDef(fieldName), new ProtectedString(true, fieldValue.ToString()));
|
||||
pwEntry.Strings.Set(EntryFieldMapper.MapFieldToPwDef(fieldName), new ProtectedString(isProtected, fieldValue.ToString()));
|
||||
break;
|
||||
case EntryFieldName.HasExpirationDate:
|
||||
pwEntry.Expires = (bool)fieldValue;
|
||||
@@ -257,7 +257,7 @@ namespace ModernKeePass.Infrastructure.KeePass
|
||||
pwEntry.ForegroundColor = (Color)fieldValue;
|
||||
break;
|
||||
default:
|
||||
pwEntry.Strings.Set(fieldName, new ProtectedString(true, fieldValue.ToString()));
|
||||
pwEntry.Strings.Set(fieldName, new ProtectedString(isProtected, fieldValue.ToString()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@@ -4,34 +4,42 @@ using System.Linq;
|
||||
using AutoMapper;
|
||||
using ModernKeePass.Domain.Entities;
|
||||
using ModernKeePassLib;
|
||||
using ModernKeePassLib.Security;
|
||||
|
||||
namespace ModernKeePass.Infrastructure.KeePass
|
||||
{
|
||||
public class EntryMappingProfile: Profile
|
||||
public class MappingProfiles: Profile
|
||||
{
|
||||
public EntryMappingProfile()
|
||||
public MappingProfiles()
|
||||
{
|
||||
CreateMap<KeyValuePair<string, ProtectedString>, FieldEntity>()
|
||||
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Key))
|
||||
.ForMember(dest => dest.Value, opt => opt.MapFrom(src => src.Value.ReadString()))
|
||||
.ForMember(dest => dest.IsProtected, opt => opt.MapFrom(src => src.Value.IsProtected));
|
||||
|
||||
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))
|
||||
.ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Uuid.ToHexString()))
|
||||
.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.MapFrom(src => GetEntryValue(src, PwDefs.UrlField)))
|
||||
.ForMember(dest => dest.Notes, opt => opt.MapFrom(src => GetEntryValue(src, PwDefs.NotesField)))
|
||||
.ForMember(dest => dest.Fields, opt => opt.MapFrom(src => src.Strings))
|
||||
.ForMember(dest => dest.ForegroundColor, opt => opt.MapFrom(src => src.ForegroundColor))
|
||||
.ForMember(dest => dest.BackgroundColor, opt => opt.MapFrom(src => src.BackgroundColor))
|
||||
.ForMember(dest => dest.ExpirationDate, opt => opt.MapFrom(src => new DateTimeOffset(src.ExpiryTime)))
|
||||
.ForMember(dest => dest.HasExpirationDate, opt => opt.MapFrom(src => src.Expires))
|
||||
.ForMember(dest => dest.Icon, opt => opt.MapFrom(src => IconMapper.MapPwIconToIcon(src.IconId)))
|
||||
.ForMember(dest => dest.AdditionalFields, opt => opt.MapFrom(src =>
|
||||
src.Strings.Where(s => !PwDefs.GetStandardFields().Contains(s.Key))
|
||||
.ToDictionary(s => s.Key, s => GetEntryValue(src, s.Key))))
|
||||
.ForMember(dest => dest.LastModificationDate, opt => opt.MapFrom(src => new DateTimeOffset(src.LastModificationTime)))
|
||||
.ForMember(dest => dest.Attachments, opt => opt.MapFrom(src => src.Binaries.Select(b => new KeyValuePair<string, byte[]> (b.Key, b.Value.ReadData()) )));
|
||||
|
||||
CreateMap<PwGroup, GroupEntity>()
|
||||
.ForMember(d => d.ParentId, opts => opts.MapFrom(s => s.ParentGroup.Uuid.ToHexString()))
|
||||
.ForMember(d => d.ParentName, opts => opts.MapFrom(s => s.ParentGroup.Name))
|
||||
.ForMember(d => d.Id, opts => opts.MapFrom(s => s.Uuid.ToHexString()))
|
||||
.ForMember(d => d.Name, opts => opts.MapFrom(s => s.Name))
|
||||
.ForMember(d => d.Icon, opts => opts.MapFrom(s => IconMapper.MapPwIconToIcon(s.IconId)))
|
||||
.ForMember(d => d.LastModificationDate, opts => opts.MapFrom(s => s.LastModificationTime))
|
||||
.ForMember(d => d.Entries, opts => opts.MapFrom(s => s.Entries))
|
||||
.ForMember(d => d.SubGroups, opts => opts.MapFrom(s => s.Groups))
|
||||
.MaxDepth(2);
|
||||
}
|
||||
|
||||
private string GetEntryValue(PwEntry entry, string key) => entry.Strings.GetSafe(key).ReadString();
|
||||
}
|
||||
}
|
@@ -3,7 +3,7 @@
|
||||
"dependencies": {
|
||||
"AutoMapper": "5.2.0",
|
||||
"Microsoft.NETCore.Portable.Compatibility": "1.0.1",
|
||||
"ModernKeePassLib": "2.44.3",
|
||||
"ModernKeePassLib": "2.45.1",
|
||||
"NETStandard.Library": "2.0.3"
|
||||
},
|
||||
"frameworks": {
|
||||
|
@@ -276,4 +276,10 @@
|
||||
<data name="CompositeKeyFileNameSuggestion" xml:space="preserve">
|
||||
<value>Key</value>
|
||||
</data>
|
||||
<data name="DatabaseTooBigDescription" xml:space="preserve">
|
||||
<value>Database size is too big for auto-save on suspend. Please save your changes before closing the app !</value>
|
||||
</data>
|
||||
<data name="DatabaseTooBigTitle" xml:space="preserve">
|
||||
<value>Attention</value>
|
||||
</data>
|
||||
</root>
|
@@ -376,7 +376,7 @@
|
||||
<value>New group</value>
|
||||
</data>
|
||||
<data name="GroupsLeftListView.HeaderLabel" xml:space="preserve">
|
||||
<value>Navigation</value>
|
||||
<value>Groups</value>
|
||||
</data>
|
||||
<data name="HistoryLeftListView.HeaderLabel" xml:space="preserve">
|
||||
<value>History</value>
|
||||
@@ -546,4 +546,16 @@
|
||||
<data name="EntryAdditionalFieldNameReserved.Text" xml:space="preserve">
|
||||
<value>Invalid field name</value>
|
||||
</data>
|
||||
<data name="EntryEnableFieldProtection.Header" xml:space="preserve">
|
||||
<value>Enable protection ?</value>
|
||||
</data>
|
||||
<data name="EntryEnableFieldProtection.OffContent" xml:space="preserve">
|
||||
<value>No</value>
|
||||
</data>
|
||||
<data name="EntryEnableFieldProtection.OnContent" xml:space="preserve">
|
||||
<value>Yes</value>
|
||||
</data>
|
||||
<data name="TopMenuRestoreButton.Content" xml:space="preserve">
|
||||
<value>Restore</value>
|
||||
</data>
|
||||
</root>
|
@@ -279,4 +279,10 @@
|
||||
<data name="EntryAddAdditionalField.Text" xml:space="preserve">
|
||||
<value>Ajouter un champ</value>
|
||||
</data>
|
||||
<data name="DatabaseTooBigDescription" xml:space="preserve">
|
||||
<value>La base de données est trop grosse pour sauvegarder automatiquement lors de la suspension. Pensez à bien sauvegarder vos changements avant de fermer l'app !</value>
|
||||
</data>
|
||||
<data name="DatabaseTooBigTitle" xml:space="preserve">
|
||||
<value>Attention</value>
|
||||
</data>
|
||||
</root>
|
@@ -379,7 +379,7 @@
|
||||
<value>Nouveau groupe</value>
|
||||
</data>
|
||||
<data name="GroupsLeftListView.HeaderLabel" xml:space="preserve">
|
||||
<value>Navigation</value>
|
||||
<value>Groupes</value>
|
||||
</data>
|
||||
<data name="HistoryLeftListView.HeaderLabel" xml:space="preserve">
|
||||
<value>Historique</value>
|
||||
@@ -543,4 +543,16 @@
|
||||
<data name="EntryAdditionalFieldNameReserved.Text" xml:space="preserve">
|
||||
<value>Nom de champ invalide</value>
|
||||
</data>
|
||||
<data name="EntryEnableFieldProtection.Header" xml:space="preserve">
|
||||
<value>Activer la protection ?</value>
|
||||
</data>
|
||||
<data name="EntryEnableFieldProtection.OffContent" xml:space="preserve">
|
||||
<value>Non</value>
|
||||
</data>
|
||||
<data name="EntryEnableFieldProtection.OnContent" xml:space="preserve">
|
||||
<value>Oui</value>
|
||||
</data>
|
||||
<data name="TopMenuRestoreButton.Content" xml:space="preserve">
|
||||
<value>Restaurer</value>
|
||||
</data>
|
||||
</root>
|
@@ -68,7 +68,7 @@ namespace ModernKeePass.ViewModels
|
||||
}
|
||||
|
||||
public ObservableCollection<EntryVm> History { get; private set; }
|
||||
public ObservableCollection<FieldVm> AdditionalFields { get; private set; }
|
||||
public ObservableCollection<EntryFieldVm> AdditionalFields { get; private set; }
|
||||
public ObservableCollection<Attachment> Attachments { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -85,8 +85,8 @@ namespace ModernKeePass.ViewModels
|
||||
if (value != null)
|
||||
{
|
||||
AdditionalFields =
|
||||
new ObservableCollection<FieldVm>(
|
||||
SelectedItem.AdditionalFields.Select(f => new FieldVm(f.Key, f.Value)));
|
||||
new ObservableCollection<EntryFieldVm>(
|
||||
SelectedItem.AdditionalFields.Select(f => new EntryFieldVm(f.Name, f.Value, f.IsProtected)));
|
||||
Attachments = new ObservableCollection<Attachment>(SelectedItem.Attachments.Select(f => new Attachment
|
||||
{
|
||||
Name = f.Key,
|
||||
@@ -131,32 +131,32 @@ namespace ModernKeePass.ViewModels
|
||||
|
||||
public string Title
|
||||
{
|
||||
get { return SelectedItem.Title; }
|
||||
get { return SelectedItem.Title.Value; }
|
||||
set
|
||||
{
|
||||
SelectedItem.Title = value;
|
||||
SetFieldValue(nameof(Title), value).Wait();
|
||||
SelectedItem.Title.Value = value;
|
||||
SetFieldValue(nameof(Title), value, true).Wait();
|
||||
}
|
||||
}
|
||||
|
||||
public string UserName
|
||||
{
|
||||
get { return SelectedItem.Username; }
|
||||
get { return SelectedItem.Username.Value; }
|
||||
set
|
||||
{
|
||||
SelectedItem.Username = value;
|
||||
SetFieldValue(nameof(UserName), value).Wait();
|
||||
SelectedItem.Username.Value = value;
|
||||
SetFieldValue(nameof(UserName), value, true).Wait();
|
||||
RaisePropertyChanged(nameof(UserName));
|
||||
}
|
||||
}
|
||||
|
||||
public string Password
|
||||
{
|
||||
get { return SelectedItem.Password; }
|
||||
get { return SelectedItem.Password.Value; }
|
||||
set
|
||||
{
|
||||
SelectedItem.Password = value;
|
||||
SetFieldValue(nameof(Password), value).Wait();
|
||||
SelectedItem.Password.Value = value;
|
||||
SetFieldValue(nameof(Password), value, true).Wait();
|
||||
RaisePropertyChanged(nameof(Password));
|
||||
RaisePropertyChanged(nameof(PasswordComplexityIndicator));
|
||||
}
|
||||
@@ -164,22 +164,22 @@ namespace ModernKeePass.ViewModels
|
||||
|
||||
public string Url
|
||||
{
|
||||
get { return SelectedItem.Url; }
|
||||
get { return SelectedItem.Url.Value; }
|
||||
set
|
||||
{
|
||||
SelectedItem.Url = value;
|
||||
SetFieldValue(nameof(Url), value).Wait();
|
||||
SelectedItem.Url.Value = value;
|
||||
SetFieldValue(nameof(Url), value, true).Wait();
|
||||
RaisePropertyChanged(nameof(Url));
|
||||
}
|
||||
}
|
||||
|
||||
public string Notes
|
||||
{
|
||||
get { return SelectedItem.Notes; }
|
||||
get { return SelectedItem.Notes.Value; }
|
||||
set
|
||||
{
|
||||
SelectedItem.Notes = value;
|
||||
SetFieldValue(nameof(Notes), value).Wait();
|
||||
SelectedItem.Notes.Value = value;
|
||||
SetFieldValue(nameof(Notes), value, true).Wait();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ namespace ModernKeePass.ViewModels
|
||||
set
|
||||
{
|
||||
SelectedItem.Icon = (Icon)Enum.Parse(typeof(Icon), value.ToString());
|
||||
SetFieldValue(nameof(Icon), SelectedItem.Icon).Wait();
|
||||
SetFieldValue(nameof(Icon), SelectedItem.Icon, true).Wait();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,7 +201,7 @@ namespace ModernKeePass.ViewModels
|
||||
if (!HasExpirationDate) return;
|
||||
|
||||
SelectedItem.ExpirationDate = value.Date;
|
||||
SetFieldValue("ExpirationDate", SelectedItem.ExpirationDate).Wait();
|
||||
SetFieldValue("ExpirationDate", SelectedItem.ExpirationDate, true).Wait();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,7 +213,7 @@ namespace ModernKeePass.ViewModels
|
||||
if (!HasExpirationDate) return;
|
||||
|
||||
SelectedItem.ExpirationDate = SelectedItem.ExpirationDate.Date.Add(value);
|
||||
SetFieldValue("ExpirationDate", SelectedItem.ExpirationDate).Wait();
|
||||
SetFieldValue("ExpirationDate", SelectedItem.ExpirationDate, true).Wait();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,7 +223,7 @@ namespace ModernKeePass.ViewModels
|
||||
set
|
||||
{
|
||||
SelectedItem.HasExpirationDate = value;
|
||||
SetFieldValue(nameof(HasExpirationDate), value).Wait();
|
||||
SetFieldValue(nameof(HasExpirationDate), value, true).Wait();
|
||||
RaisePropertyChanged(nameof(HasExpirationDate));
|
||||
}
|
||||
}
|
||||
@@ -234,7 +234,7 @@ namespace ModernKeePass.ViewModels
|
||||
set
|
||||
{
|
||||
SelectedItem.BackgroundColor = value.ToColor();
|
||||
SetFieldValue(nameof(BackgroundColor), SelectedItem.BackgroundColor).Wait();
|
||||
SetFieldValue(nameof(BackgroundColor), SelectedItem.BackgroundColor, true).Wait();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,7 +244,7 @@ namespace ModernKeePass.ViewModels
|
||||
set
|
||||
{
|
||||
SelectedItem.ForegroundColor = value.ToColor();
|
||||
SetFieldValue(nameof(ForegroundColor), SelectedItem.ForegroundColor).Wait();
|
||||
SetFieldValue(nameof(ForegroundColor), SelectedItem.ForegroundColor, true).Wait();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,7 +269,7 @@ namespace ModernKeePass.ViewModels
|
||||
public RelayCommand GoBackCommand { get; }
|
||||
public RelayCommand GoToParentCommand { get; set; }
|
||||
public RelayCommand AddAdditionalField { get; set; }
|
||||
public RelayCommand<FieldVm> DeleteAdditionalField { get; set; }
|
||||
public RelayCommand<EntryFieldVm> DeleteAdditionalField { get; set; }
|
||||
public RelayCommand<Attachment> OpenAttachmentCommand { get; set; }
|
||||
public RelayCommand AddAttachmentCommand { get; set; }
|
||||
public RelayCommand<Attachment> DeleteAttachmentCommand { get; set; }
|
||||
@@ -308,14 +308,14 @@ namespace ModernKeePass.ViewModels
|
||||
GoBackCommand = new RelayCommand(() => _navigation.GoBack());
|
||||
GoToParentCommand = new RelayCommand(() => GoToGroup(_parent.Id));
|
||||
AddAdditionalField = new RelayCommand(AddField, () => IsCurrentEntry);
|
||||
DeleteAdditionalField = new RelayCommand<FieldVm>(async field => await DeleteField(field), field => field != null && IsCurrentEntry);
|
||||
DeleteAdditionalField = new RelayCommand<EntryFieldVm>(async field => await DeleteField(field), field => field != null && IsCurrentEntry);
|
||||
OpenAttachmentCommand = new RelayCommand<Attachment>(async attachment => await OpenAttachment(attachment));
|
||||
AddAttachmentCommand = new RelayCommand(async () => await AddAttachment(), () => IsCurrentEntry);
|
||||
DeleteAttachmentCommand = new RelayCommand<Attachment>(async attachment => await DeleteAttachment(attachment), _ => IsCurrentEntry);
|
||||
|
||||
MessengerInstance.Register<DatabaseSavedMessage>(this, _ => SaveCommand.RaiseCanExecuteChanged());
|
||||
MessengerInstance.Register<EntryFieldValueChangedMessage>(this, async message => await SetFieldValue(message.FieldName, message.FieldValue));
|
||||
MessengerInstance.Register<EntryFieldNameChangedMessage>(this, async message => await UpdateFieldName(message.OldName, message.NewName, message.Value));
|
||||
MessengerInstance.Register<EntryFieldValueChangedMessage>(this, async message => await SetFieldValue(message.FieldName, message.FieldValue, message.IsProtected));
|
||||
MessengerInstance.Register<EntryFieldNameChangedMessage>(this, async message => await UpdateFieldName(message.OldName, message.NewName, message.Value, message.IsProtected));
|
||||
}
|
||||
|
||||
public async Task Initialize(string entryId)
|
||||
@@ -348,6 +348,7 @@ namespace ModernKeePass.ViewModels
|
||||
});
|
||||
RaisePropertyChanged(nameof(IsRevealPasswordEnabled));
|
||||
}
|
||||
|
||||
public async Task AddHistory()
|
||||
{
|
||||
if (_isDirty) await _mediator.Send(new AddHistoryCommand { Entry = History[0] });
|
||||
@@ -365,26 +366,26 @@ namespace ModernKeePass.ViewModels
|
||||
GoToGroup(destination);
|
||||
}
|
||||
|
||||
private async Task SetFieldValue(string fieldName, object value)
|
||||
private async Task SetFieldValue(string fieldName, object value, bool isProtected)
|
||||
{
|
||||
await _mediator.Send(new UpsertFieldCommand { EntryId = Id, FieldName = fieldName, FieldValue = value });
|
||||
await _mediator.Send(new UpsertFieldCommand { EntryId = Id, FieldName = fieldName, FieldValue = value, IsProtected = isProtected});
|
||||
SaveCommand.RaiseCanExecuteChanged();
|
||||
_isDirty = true;
|
||||
}
|
||||
|
||||
private async Task UpdateFieldName(string oldName, string newName, string value)
|
||||
private async Task UpdateFieldName(string oldName, string newName, string value, bool isProtected)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(oldName)) await _mediator.Send(new DeleteFieldCommand { EntryId = Id, FieldName = oldName });
|
||||
await SetFieldValue(newName, value);
|
||||
await SetFieldValue(newName, value, isProtected);
|
||||
}
|
||||
|
||||
private void AddField()
|
||||
{
|
||||
AdditionalFields.Add(new FieldVm(string.Empty, string.Empty));
|
||||
AdditionalFields.Add(new EntryFieldVm(string.Empty, string.Empty, false));
|
||||
AdditionalFieldSelectedIndex = AdditionalFields.Count - 1;
|
||||
}
|
||||
|
||||
private async Task DeleteField(FieldVm field)
|
||||
private async Task DeleteField(EntryFieldVm field)
|
||||
{
|
||||
AdditionalFields.Remove(field);
|
||||
if (!string.IsNullOrEmpty(field.Name))
|
||||
|
@@ -43,7 +43,7 @@ namespace ModernKeePass.ViewModels
|
||||
public bool IsNotRoot => Database.RootGroupId != _group.Id;
|
||||
|
||||
public IOrderedEnumerable<IGrouping<char, EntryVm>> EntriesZoomedOut => from e in Entries
|
||||
group e by e.Title.ToUpper().FirstOrDefault() into grp
|
||||
group e by e.Title.Name.ToUpper().FirstOrDefault() into grp
|
||||
orderby grp.Key
|
||||
select grp;
|
||||
|
||||
|
@@ -441,8 +441,8 @@
|
||||
</ToolTipService.ToolTip>
|
||||
</SymbolIcon>
|
||||
<StackPanel Grid.Column="1" x:Name="ExpirationDatePanel" Orientation="Vertical" Visibility="{Binding HasExpirationDate, Converter={StaticResource BooleanToVisibilityConverter}}">
|
||||
<DatePicker Margin="0,0,20,0" Date="{Binding ExpiryDate, Mode=TwoWay}" />
|
||||
<TimePicker Margin="0,10,0,0" Time="{Binding ExpiryTime, Mode=TwoWay}" />
|
||||
<DatePicker Margin="10,5,20,0" Date="{Binding ExpiryDate, Mode=TwoWay}" />
|
||||
<TimePicker Margin="10,10,0,0" Time="{Binding ExpiryTime, Mode=TwoWay}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
@@ -481,40 +481,51 @@
|
||||
</HubSection>
|
||||
<HubSection x:Uid="EntryHubAdditional">
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Vertical">
|
||||
<HyperlinkButton Command="{Binding Path=DataContext.AddAdditionalField, ElementName=Page}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<SymbolIcon Symbol="Add" />
|
||||
<TextBlock x:Uid="EntryAddAdditionalField" VerticalAlignment="Center" Margin="10,0,0,0" />
|
||||
</StackPanel>
|
||||
</HyperlinkButton>
|
||||
<Border BorderBrush="DarkGray" BorderThickness="0,0,0,1" />
|
||||
<local:SelectableTemplateListView
|
||||
ItemsSource="{Binding AdditionalFields}"
|
||||
SelectedIndex="{Binding AdditionalFieldSelectedIndex, Mode=TwoWay}"
|
||||
ItemContainerStyle="{StaticResource ListViewLeftIndicatorItemExpanded}">
|
||||
<local:SelectableTemplateListView.SelectedItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Vertical" Margin="5">
|
||||
<TextBox Text="{Binding Name, Mode=TwoWay}" Width="350"
|
||||
IsEnabled="{Binding Path=DataContext.IsCurrentEntry, ElementName=Page}" />
|
||||
<TextBox HorizontalAlignment="Left" AcceptsReturn="True" Height="100" TextWrapping="Wrap" Width="350" Margin="0,5,0,0"
|
||||
Text="{Binding Value, Mode=TwoWay}"
|
||||
IsEnabled="{Binding Path=DataContext.IsCurrentEntry, ElementName=Page}" />
|
||||
<Button x:Uid="EntryDeleteAdditionalField" HorizontalAlignment="Right" Command="{Binding Path=DataContext.DeleteAdditionalField, ElementName=Page}" CommandParameter="{Binding}" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</local:SelectableTemplateListView.SelectedItemTemplate>
|
||||
<local:SelectableTemplateListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Vertical" Margin="5">
|
||||
<TextBlock Text="{Binding Name}" Style="{StaticResource EntryTextBlockStyle}" FontWeight="SemiBold" />
|
||||
<TextBlock HorizontalAlignment="Left" MaxLines="3" FontSize="12" Margin="2,0,2,5" Text="{Binding Value}" Style="{StaticResource EntryTextBlockStyle}"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</local:SelectableTemplateListView.ItemTemplate>
|
||||
</local:SelectableTemplateListView>
|
||||
</StackPanel>
|
||||
<local:SelectableTemplateListView
|
||||
ItemsSource="{Binding AdditionalFields}"
|
||||
SelectedIndex="{Binding AdditionalFieldSelectedIndex, Mode=TwoWay}"
|
||||
ItemContainerStyle="{StaticResource ListViewLeftIndicatorItemExpanded}">
|
||||
<local:SelectableTemplateListView.HeaderTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Vertical">
|
||||
<HyperlinkButton Command="{Binding Path=DataContext.AddAdditionalField, ElementName=Page}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<SymbolIcon Symbol="Add" />
|
||||
<TextBlock x:Uid="EntryAddAdditionalField" VerticalAlignment="Center" Margin="10,0,0,0" />
|
||||
</StackPanel>
|
||||
</HyperlinkButton>
|
||||
<Border BorderBrush="DarkGray" BorderThickness="0,0,0,1" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</local:SelectableTemplateListView.HeaderTemplate>
|
||||
<local:SelectableTemplateListView.SelectedItemTemplate>
|
||||
<DataTemplate>
|
||||
<Grid Margin="5">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBox Grid.Row="0" Text="{Binding Name, Mode=TwoWay}" Width="350"
|
||||
IsEnabled="{Binding Path=DataContext.IsCurrentEntry, ElementName=Page}" />
|
||||
<TextBox Grid.Row="1" AcceptsReturn="True" Height="100" TextWrapping="Wrap" Width="350" Margin="0,5,0,0"
|
||||
Text="{Binding Value, Mode=TwoWay}"
|
||||
IsEnabled="{Binding Path=DataContext.IsCurrentEntry, ElementName=Page}" />
|
||||
<ToggleSwitch Grid.Row="2" x:Uid="EntryEnableFieldProtection" HorizontalAlignment="Left" IsOn="{Binding IsProtected, Mode=TwoWay}" />
|
||||
<Button Grid.Row="2" x:Uid="EntryDeleteAdditionalField" HorizontalAlignment="Right" Margin="0,15,0,0" Command="{Binding Path=DataContext.DeleteAdditionalField, ElementName=Page}" CommandParameter="{Binding}" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</local:SelectableTemplateListView.SelectedItemTemplate>
|
||||
<local:SelectableTemplateListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Vertical" Margin="5">
|
||||
<TextBlock Text="{Binding Name}" Style="{StaticResource EntryTextBlockStyle}" FontWeight="SemiBold" />
|
||||
<TextBlock HorizontalAlignment="Left" MaxLines="3" FontSize="12" Margin="2,0,2,5" Text="*****" Visibility="{Binding IsProtected, Converter={StaticResource BooleanToVisibilityConverter}}" Style="{StaticResource EntryTextBlockStyle}"/>
|
||||
<TextBlock HorizontalAlignment="Left" MaxLines="3" FontSize="12" Margin="2,0,2,5" Text="{Binding Value}" Visibility="{Binding IsProtected, Converter={StaticResource InverseBooleanToVisibilityConverter}}" Style="{StaticResource EntryTextBlockStyle}"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</local:SelectableTemplateListView.ItemTemplate>
|
||||
</local:SelectableTemplateListView>
|
||||
</DataTemplate>
|
||||
</HubSection>
|
||||
<HubSection x:Uid="EntryHubAttachments" Foreground="{StaticResource HubSectionBrush}">
|
||||
|
@@ -221,7 +221,7 @@ namespace ModernKeePass.Views.UserControls
|
||||
var results = (await Model.Search(args.QueryText)).Take(5);
|
||||
foreach (var result in results)
|
||||
{
|
||||
args.Request.SearchSuggestionCollection.AppendResultSuggestion(result.Title, result.ParentGroupName, result.Id, imageUri, string.Empty);
|
||||
args.Request.SearchSuggestionCollection.AppendResultSuggestion(result.Title.Value, result.ParentGroupName, result.Id, imageUri, string.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -372,8 +372,8 @@
|
||||
<HintPath>..\packages\HockeySDK.WINRT.4.1.6\lib\portable-win81\Microsoft.HockeyApp.Kit.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="ModernKeePassLib, Version=2.44.3.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ModernKeePassLib.2.44.3\lib\netstandard1.2\ModernKeePassLib.dll</HintPath>
|
||||
<Reference Include="ModernKeePassLib, Version=2.45.1.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\ModernKeePassLib.2.45.1\lib\netstandard1.2\ModernKeePassLib.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="SixLabors.Core, Version=0.1.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
|
@@ -1,4 +1,5 @@
|
||||
Support for additional fields
|
||||
Support for attachments
|
||||
Ability to manually reorder groups
|
||||
Design changes
|
||||
Design changes
|
||||
Update to KeePassLib version 2.45
|
@@ -1,4 +1,5 @@
|
||||
Ajout des champs additionnels
|
||||
Ajout des pi<70>ces-jointes
|
||||
Possibilite de reorganiser les groupes manuellement
|
||||
Quelques changements de design
|
||||
Quelques changements de design
|
||||
Mise a jour de la KeePassLib version 2.45
|
@@ -14,7 +14,7 @@
|
||||
<package id="Microsoft.NETCore.Platforms" version="2.1.1" targetFramework="win81" />
|
||||
<package id="Microsoft.NETCore.Portable.Compatibility" version="1.0.1" targetFramework="win81" />
|
||||
<package id="Microsoft.NETCore.UniversalWindowsPlatform" version="6.1.7" targetFramework="win81" />
|
||||
<package id="ModernKeePassLib" version="2.44.3" targetFramework="win81" />
|
||||
<package id="ModernKeePassLib" version="2.45.1" targetFramework="win81" />
|
||||
<package id="MvvmLight" version="5.4.1.1" targetFramework="win81" />
|
||||
<package id="MvvmLightLibs" version="5.4.1.1" targetFramework="win81" />
|
||||
<package id="NETStandard.Library" version="2.0.3" targetFramework="win81" />
|
||||
|
@@ -5,5 +5,6 @@
|
||||
public string OldName { get; set; }
|
||||
public string NewName { get; set; }
|
||||
public string Value { get; set; }
|
||||
public bool IsProtected { get; set; }
|
||||
}
|
||||
}
|
@@ -4,5 +4,6 @@
|
||||
{
|
||||
public string FieldName { get; set; }
|
||||
public string FieldValue { get; set; }
|
||||
public bool IsProtected { get; set; }
|
||||
}
|
||||
}
|
51
WinAppCommon/ViewModels/Items/EntryFieldVm.cs
Normal file
51
WinAppCommon/ViewModels/Items/EntryFieldVm.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System.Linq;
|
||||
using GalaSoft.MvvmLight;
|
||||
using Messages;
|
||||
using ModernKeePass.Domain.Enums;
|
||||
|
||||
namespace ModernKeePass.ViewModels.ListItems
|
||||
{
|
||||
public class EntryFieldVm: ViewModelBase
|
||||
{
|
||||
private string _name;
|
||||
private string _value;
|
||||
private bool _isProtected;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return _name; }
|
||||
set
|
||||
{
|
||||
var newName = EntryFieldName.StandardFieldNames.Contains(value) ? $"{value}_1" : value;
|
||||
MessengerInstance.Send(new EntryFieldNameChangedMessage { OldName = Name, NewName = newName, Value = Value, IsProtected = IsProtected});
|
||||
Set(nameof(Name), ref _name, newName);
|
||||
}
|
||||
}
|
||||
|
||||
public string Value
|
||||
{
|
||||
get { return _value; }
|
||||
set
|
||||
{
|
||||
MessengerInstance.Send(new EntryFieldValueChangedMessage { FieldName = Name, FieldValue = value, IsProtected = IsProtected });
|
||||
Set(nameof(Value), ref _value, value);
|
||||
}
|
||||
}
|
||||
public bool IsProtected
|
||||
{
|
||||
get { return _isProtected; }
|
||||
set
|
||||
{
|
||||
MessengerInstance.Send(new EntryFieldValueChangedMessage { FieldName = Name, FieldValue = Value, IsProtected = value });
|
||||
Set(nameof(IsProtected), ref _isProtected, value);
|
||||
}
|
||||
}
|
||||
|
||||
public EntryFieldVm(string fieldName, string fieldValue, bool isProtected)
|
||||
{
|
||||
_name = fieldName;
|
||||
_value = fieldValue;
|
||||
_isProtected = isProtected;
|
||||
}
|
||||
}
|
||||
}
|
@@ -4,6 +4,7 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using GalaSoft.MvvmLight;
|
||||
using GalaSoft.MvvmLight.Command;
|
||||
using GalaSoft.MvvmLight.Views;
|
||||
using MediatR;
|
||||
using Messages;
|
||||
using ModernKeePass.Application.Common.Interfaces;
|
||||
@@ -93,6 +94,7 @@ namespace ModernKeePass.ViewModels
|
||||
private readonly IResourceProxy _resource;
|
||||
private readonly INotificationService _notification;
|
||||
private readonly IFileProxy _file;
|
||||
private readonly IDialogService _dialog;
|
||||
private bool _hasPassword;
|
||||
private bool _hasKeyFile;
|
||||
private bool _isOpening;
|
||||
@@ -102,12 +104,13 @@ namespace ModernKeePass.ViewModels
|
||||
private string _keyFileText;
|
||||
private bool _isError;
|
||||
|
||||
public OpenDatabaseControlVm(IMediator mediator, IResourceProxy resource, INotificationService notification, IFileProxy file)
|
||||
public OpenDatabaseControlVm(IMediator mediator, IResourceProxy resource, INotificationService notification, IFileProxy file, IDialogService dialog)
|
||||
{
|
||||
_mediator = mediator;
|
||||
_resource = resource;
|
||||
_notification = notification;
|
||||
_file = file;
|
||||
_dialog = dialog;
|
||||
OpenKeyFileCommand = new RelayCommand(async () => await OpenKeyFile());
|
||||
OpenDatabaseCommand = new RelayCommand<string>(async databaseFilePath => await TryOpenDatabase(databaseFilePath), _ => IsValid);
|
||||
_keyFileText = _resource.GetResourceValue("CompositeKeyDefaultKeyFile");
|
||||
@@ -130,7 +133,7 @@ namespace ModernKeePass.ViewModels
|
||||
if (database.IsDirty)
|
||||
{
|
||||
MessengerInstance.Register<DatabaseClosedMessage>(this, async message => await OpenDatabase(message.Parameter as string));
|
||||
MessengerInstance.Send(new DatabaseAlreadyOpenedMessage {Parameter = databaseFilePath});
|
||||
MessengerInstance.Send(new DatabaseAlreadyOpenedMessage { Parameter = databaseFilePath });
|
||||
}
|
||||
else await OpenDatabase(databaseFilePath);
|
||||
}
|
||||
@@ -146,9 +149,11 @@ namespace ModernKeePass.ViewModels
|
||||
KeyFilePath = HasKeyFile ? KeyFilePath : null,
|
||||
Password = HasPassword ? Password : null,
|
||||
});
|
||||
var rootGroupId = (await _mediator.Send(new GetDatabaseQuery())).RootGroupId;
|
||||
var database = await _mediator.Send(new GetDatabaseQuery());
|
||||
|
||||
MessengerInstance.Send(new DatabaseOpenedMessage { RootGroupId = rootGroupId });
|
||||
if (database.Size > Common.Constants.File.OneMegaByte)
|
||||
await _dialog.ShowMessage(_resource.GetResourceValue("DatabaseTooBigDescription"), _resource.GetResourceValue("DatabaseTooBigTitle"));
|
||||
MessengerInstance.Send(new DatabaseOpenedMessage { RootGroupId = database.RootGroupId });
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
|
@@ -42,7 +42,7 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Messages\NavigateToPageMessage.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Messages\SaveErrorMessage.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\AboutVm.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\Items\FieldVm.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\Items\EntryFieldVm.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\ViewModelLocatorCommon.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\Items\ListMenuItemVm.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\Items\MainMenuItemVm.cs" />
|
||||
|
Reference in New Issue
Block a user