vault unlocking WIP
This commit is contained in:
@@ -1,3 +1,3 @@
|
||||
namespace Bitvault;
|
||||
|
||||
public record Locked;
|
||||
public record Closed;
|
||||
@@ -20,18 +20,20 @@ public class CreateVaultHandler(IVaultComponentFactory componentFactory) :
|
||||
IContainer<VaultKey> vaultKeyContainer = host.Services.GetRequiredService<IContainer<VaultKey>>();
|
||||
IVaultStorage vaultStorage = host.Services.GetRequiredService<IVaultStorage>();
|
||||
|
||||
VaultKey key = keyVaultFactory.Create(Encoding.UTF8.GetBytes(password));
|
||||
vaultKeyContainer.Set(key);
|
||||
|
||||
if (await vaultStorage.CreateAsync(name, key))
|
||||
if (keyVaultFactory.Create(Encoding.UTF8.GetBytes(password)) is VaultKey key)
|
||||
{
|
||||
IWritableConfiguration<VaultConfiguration> configuration =
|
||||
host.Services.GetRequiredService<IWritableConfiguration<VaultConfiguration>>();
|
||||
vaultKeyContainer.Set(key);
|
||||
|
||||
configuration.Write(args => args.Key = $"{Convert.ToBase64String(key.Salt)}:{Convert.ToBase64String(key.EncryptedKey)}:{Convert.ToBase64String(key.DecryptedKey)}");
|
||||
host.Start();
|
||||
if (await vaultStorage.Create(name, key))
|
||||
{
|
||||
IWritableConfiguration<VaultConfiguration> configuration =
|
||||
host.Services.GetRequiredService<IWritableConfiguration<VaultConfiguration>>();
|
||||
|
||||
return true;
|
||||
configuration.Write(args => args.Key = $"{Convert.ToBase64String(key.Salt)}:{Convert.ToBase64String(key.EncryptedKey)}:{Convert.ToBase64String(key.DecryptedKey)}");
|
||||
host.Start();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
public interface IVaultKeyFactory
|
||||
{
|
||||
VaultKey Create(byte[] phrase,
|
||||
VaultKey? Create(byte[] phrase,
|
||||
byte[]? encryptedKey = null,
|
||||
byte[]? salt = null);
|
||||
}
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
|
||||
public interface IVaultStorage
|
||||
{
|
||||
Task<bool> CreateAsync(string name, VaultKey key);
|
||||
Task<bool> Create(string name, VaultKey key);
|
||||
}
|
||||
@@ -18,10 +18,12 @@ public class OpenVaultHandler(VaultConfiguration configuration,
|
||||
byte[]? salt = Convert.FromBase64String(keyPart[0]);
|
||||
byte[]? encryptedKey = Convert.FromBase64String(keyPart[1]);
|
||||
|
||||
VaultKey key = keyVaultFactory.Create(Encoding.UTF8.GetBytes(password), encryptedKey, salt);
|
||||
if (await vaultStorage.CreateAsync(name, key))
|
||||
if ( keyVaultFactory.Create(Encoding.UTF8.GetBytes(password), encryptedKey, salt) is VaultKey key)
|
||||
{
|
||||
|
||||
if (await vaultStorage.Create(name, key))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ using Toolkit.Foundation;
|
||||
|
||||
namespace Bitvault;
|
||||
|
||||
public partial class LockViewModel(IServiceProvider provider,
|
||||
public partial class OpenVaultViewModel(IServiceProvider provider,
|
||||
IServiceFactory factory,
|
||||
IMediator mediator,
|
||||
IPublisher publisher,
|
||||
@@ -16,11 +16,14 @@ public partial class LockViewModel(IServiceProvider provider,
|
||||
private string? password;
|
||||
|
||||
[RelayCommand]
|
||||
private void Unlock()
|
||||
private async Task Invoke()
|
||||
{
|
||||
if (Password is { Length: > 0 })
|
||||
{
|
||||
Mediator.Handle<Open<Vault>, bool>(Open.As(new Vault(Password)));
|
||||
if (await Mediator.Handle<Open<Vault>, bool>(Open.As(new Vault(Password))))
|
||||
{
|
||||
await Publisher.Publish<Opened>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
namespace Bitvault;
|
||||
|
||||
public record Unlocked;
|
||||
public record Opened;
|
||||
@@ -8,15 +8,25 @@ public class VaultKeyFactory(IKeyGenerator generator,
|
||||
IDecryptor decryptor) :
|
||||
IVaultKeyFactory
|
||||
{
|
||||
public VaultKey Create(byte[] phrase,
|
||||
public VaultKey? Create(byte[] phrase,
|
||||
byte[]? encryptedKey = null,
|
||||
byte[]? salt = null)
|
||||
{
|
||||
salt ??= generator.Generate(16);
|
||||
byte[] derivedKey = deriver.DeriveKey(phrase, salt);
|
||||
|
||||
encryptedKey ??= encryptor.Encrypt(generator.Generate(32), derivedKey);
|
||||
byte[] decryptedKey = decryptor.Decrypt(encryptedKey, derivedKey);
|
||||
if (encryptedKey is null)
|
||||
{
|
||||
if (!encryptor.TryEncrypt(generator.Generate(32), derivedKey, out encryptedKey) || encryptedKey is null)
|
||||
{
|
||||
return default;
|
||||
}
|
||||
}
|
||||
|
||||
if (!decryptor.TryDecrypt(encryptedKey, derivedKey, out byte[]? decryptedKey) || decryptedKey is null)
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
return new VaultKey(salt, encryptedKey, decryptedKey);
|
||||
}
|
||||
|
||||
@@ -6,15 +6,21 @@ namespace Bitvault;
|
||||
public partial class VaultNavigationViewModel :
|
||||
ObservableCollectionViewModel<IVaultNavigationViewModel>,
|
||||
IMainNavigationViewModel,
|
||||
INotificationHandler<Unlocked>,
|
||||
INotificationHandler<Locked>
|
||||
INotificationHandler<Opened>,
|
||||
INotificationHandler<Closed>
|
||||
{
|
||||
[ObservableProperty]
|
||||
private bool locked;
|
||||
private bool expanded = true;
|
||||
|
||||
[ObservableProperty]
|
||||
private string name;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool opened;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool selected;
|
||||
|
||||
public VaultNavigationViewModel(IServiceProvider provider,
|
||||
IServiceFactory factory,
|
||||
IMediator mediator,
|
||||
@@ -30,9 +36,9 @@ public partial class VaultNavigationViewModel :
|
||||
|
||||
public IContentTemplate Template { get; set; }
|
||||
|
||||
public Task Handle(Unlocked args, CancellationToken cancellationToken = default)
|
||||
public Task Handle(Opened args, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Locked = true;
|
||||
Opened = true;
|
||||
|
||||
Add<AllNavigationViewModel>();
|
||||
Add<StarredNavigationViewModel>();
|
||||
@@ -42,9 +48,9 @@ public partial class VaultNavigationViewModel :
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task Handle(Locked args, CancellationToken cancellationToken = default)
|
||||
public Task Handle(Closed args, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Locked = true;
|
||||
Opened = true;
|
||||
Clear();
|
||||
|
||||
return Task.CompletedTask;
|
||||
|
||||
@@ -10,7 +10,7 @@ public class VaultStorage(IContainer<VaultStorageConnection> connection,
|
||||
IServiceProvider provider) :
|
||||
IVaultStorage
|
||||
{
|
||||
public async Task<bool> CreateAsync(string name,
|
||||
public async Task<bool> Create(string name,
|
||||
VaultKey key)
|
||||
{
|
||||
connection.Set(new VaultStorageConnection($"Data Source={Path.Combine(environment.ContentRootPath, name)}" +
|
||||
|
||||
Reference in New Issue
Block a user