From 9ba2cfb4d51a6faea8e8ffce4c84b64a4fa59753 Mon Sep 17 00:00:00 2001 From: Michiel Post Date: Fri, 18 Oct 2024 14:32:12 +0200 Subject: [PATCH] Setup for unlock dialog --- src/aoWebWallet/Models/Wallet.cs | 2 + .../Pages/GenerateWalletPage.razor | 65 ++++++++++--------- .../Shared/UnlockWalletComponent.razor | 30 +++++++++ .../Shared/UnlockWalletDialog.razor | 52 +++++++++++++++ src/aoWebWallet/ViewModels/MainViewModel.cs | 25 +++++++ 5 files changed, 144 insertions(+), 30 deletions(-) create mode 100644 src/aoWebWallet/Shared/UnlockWalletComponent.razor create mode 100644 src/aoWebWallet/Shared/UnlockWalletDialog.razor diff --git a/src/aoWebWallet/Models/Wallet.cs b/src/aoWebWallet/Models/Wallet.cs index 570a20f..cb2322f 100644 --- a/src/aoWebWallet/Models/Wallet.cs +++ b/src/aoWebWallet/Models/Wallet.cs @@ -27,8 +27,10 @@ public class Wallet public DateTimeOffset AddedDate { get; set; } public DateTimeOffset LastUsedDate { get; set; } + [JsonIgnore] public bool NeedsUnlock => JwkEncrypted != null && JwkSecret == null; + [JsonIgnore] public bool NeedsBackup => Source == WalletTypes.Generated && !string.IsNullOrEmpty(Jwk) && !LastBackedUpDate.HasValue; public string? GetJwkSecret() diff --git a/src/aoWebWallet/Pages/GenerateWalletPage.razor b/src/aoWebWallet/Pages/GenerateWalletPage.razor index d4971f5..9a632a1 100644 --- a/src/aoWebWallet/Pages/GenerateWalletPage.razor +++ b/src/aoWebWallet/Pages/GenerateWalletPage.razor @@ -9,39 +9,44 @@ @if (BindingContext.SecretKey == null) { - - Generate Wallet - Enter a password to encrypt your wallet. The password must be at least 6 characters long. + if (BindingContext.CheckNeedsUnlock()) + { + + } + else + { + + Generate Wallet + Enter a password to encrypt your wallet. The password must be at least 6 characters long. - + - + - - Generate Wallet - - + + Generate Wallet + + + } } else { diff --git a/src/aoWebWallet/Shared/UnlockWalletComponent.razor b/src/aoWebWallet/Shared/UnlockWalletComponent.razor new file mode 100644 index 0000000..16a84b5 --- /dev/null +++ b/src/aoWebWallet/Shared/UnlockWalletComponent.razor @@ -0,0 +1,30 @@ +@using aoWebWallet.Models +@inherits MvvmComponentBase +@inject ISnackbar Snackbar + + + + Wallets are locked. Please unlock the wallets. + +
+ + Unlock Wallet + +
+
+
+ + + +@code { + + public string? Progress { get; set; } + + + public async Task Submit() + { + await BindingContext.TriggerUnlock(); + + return true; + } +} diff --git a/src/aoWebWallet/Shared/UnlockWalletDialog.razor b/src/aoWebWallet/Shared/UnlockWalletDialog.razor new file mode 100644 index 0000000..836d1ca --- /dev/null +++ b/src/aoWebWallet/Shared/UnlockWalletDialog.razor @@ -0,0 +1,52 @@ +@using aoww.Services +@inject ISnackbar Snackbar +@inherits MvvmComponentBase + + + + Unlock Wallets + + + + @Progress + + + Cancel + Unlock + + +@code { + [CascadingParameter] MudDialogInstance MudDialog { get; set; } = default!; + + public string? Password { get; set; } + public string? Progress { get; set; } + + public void Submit() + { + if (string.IsNullOrEmpty(Password)) + return; + + BindingContext.SecretKey = Password; + + try + { + foreach(var wallet in BindingContext.WalletList.Data ?? new()) + { + if(wallet.NeedsUnlock) + { + if (wallet.JwkEncrypted == null) + continue; + + wallet.JwkSecret = EncryptionService.DecryptWallet(Password, wallet.JwkEncrypted); + } + } + } + catch + { + Progress = "Could not unlock wallets."; + } + } + + //void Submit() => MudDialog.Close(DialogResult.Ok(true)); + void Cancel() => MudDialog.Cancel(); +} \ No newline at end of file diff --git a/src/aoWebWallet/ViewModels/MainViewModel.cs b/src/aoWebWallet/ViewModels/MainViewModel.cs index 917d06c..1daded9 100644 --- a/src/aoWebWallet/ViewModels/MainViewModel.cs +++ b/src/aoWebWallet/ViewModels/MainViewModel.cs @@ -2,6 +2,7 @@ using aoWebWallet.Models; using aoWebWallet.Pages; using aoWebWallet.Services; +using aoWebWallet.Shared; using aoww.Services; using aoww.Services.Models; using ArweaveAO; @@ -29,6 +30,7 @@ public partial class MainViewModel : ObservableRecipient private readonly ArweaveService arweaveService; private readonly GraphqlClient graphqlClient; private readonly MemoryDataCache memoryDataCache; + private readonly IDialogService dialogService; private readonly ArweaveConfig arweaveConfig; private readonly GatewayConfig gatewayConfig; private readonly GraphqlConfig graphqlConfig; @@ -62,6 +64,7 @@ public MainViewModel(TokenDataService dataService, ArweaveService arweaveService, GraphqlClient graphqlClient, MemoryDataCache memoryDataCache, + IDialogService dialogService, IOptions graphqlConfig, IOptions gatewayConfig, IOptions arweaveConfig) : base() @@ -71,6 +74,7 @@ public MainViewModel(TokenDataService dataService, this.arweaveService = arweaveService; this.graphqlClient = graphqlClient; this.memoryDataCache = memoryDataCache; + this.dialogService = dialogService; this.arweaveConfig = arweaveConfig.Value; this.gatewayConfig = gatewayConfig.Value; this.graphqlConfig = graphqlConfig.Value; @@ -81,6 +85,27 @@ public async Task AddToLog(ActivityLogType type, string id) await storageService.AddToLog(type, id); } + public bool CheckNeedsUnlock() + { + Console.WriteLine($"Wallets: {WalletList.Data?.Count}"); + Console.WriteLine($"Wallets need unlock: {WalletList.Data?.Where(x => x.NeedsUnlock)?.Count()}"); + + return WalletList.Data?.Any(x => x.NeedsUnlock) ?? false; + } + + public Task TriggerUnlock() + { + if (WalletList.Data?.Any(x => x.NeedsUnlock) ?? false) + { + + var options = new DialogOptions { CloseOnEscapeKey = true }; + + return dialogService.ShowAsync("Unlock Wallet", options); + } + + return Task.CompletedTask; + } + public Task LoadProcessesDataList() => ProcessesDataList.DataLoader.LoadAsync(async () => {