diff --git a/src/BolWallet/Constants.cs b/src/BolWallet/Constants.cs index 6949b78..7957652 100644 --- a/src/BolWallet/Constants.cs +++ b/src/BolWallet/Constants.cs @@ -9,13 +9,15 @@ internal class Constants public const string BirthDateFormat = "yyyy-MM-dd"; public const string MainNet = "mainnet"; public const string TestNet = "testnet"; - + public const string DefaultHash = "0000000000000000000000000000000000000000000000000000000000000000"; + // Preferences Keys public const string TargetNet = "target-net"; // Static messages to re-use public static readonly TargetNetworkChangedMessage TargetNetworkChangedMessage = new(); public static readonly WalletClosedMessage WalletClosedMessage = new(); + public static readonly WalletCreatedMessage WalletCreatedMessage = new(); public static readonly JsonSerializerOptions WalletJsonSerializerDefaultOptions = new() { diff --git a/src/BolWallet/Models/EncryptedCitizenshipForm.cs b/src/BolWallet/Models/EncryptedCitizenshipForm.cs index 33b96e4..78efe28 100644 --- a/src/BolWallet/Models/EncryptedCitizenshipForm.cs +++ b/src/BolWallet/Models/EncryptedCitizenshipForm.cs @@ -47,20 +47,55 @@ public string ThirdName set => _thirdName = value?.ToUpper() ?? ""; } + private string _identityCardSha256; + + [RegularExpression("^[A-F0-9]*$", ErrorMessage = "Only capital letters and numbers are allowed.")] [StringLength(64, MinimumLength = 64, ErrorMessage = "The SHA-256 hash must be exactly 64 characters.")] - public string IdentityCardSha256 { get; set; } + public string IdentityCardSha256 + { + get => _identityCardSha256; + set => _identityCardSha256 = value?.ToUpper(); + } + + private string _identityCardBackSha256; + [RegularExpression("^[A-F0-9]*$", ErrorMessage = "Only capital letters and numbers are allowed.")] [StringLength(64, MinimumLength = 64, ErrorMessage = "The SHA-256 hash must be exactly 64 characters.")] - public string IdentityCardBackSha256 { get; set; } + public string IdentityCardBackSha256 + { + get => _identityCardBackSha256; + set => _identityCardBackSha256 = value?.ToUpper(); + } + private string _passportSha256; + + [RegularExpression("^[A-F0-9]*$", ErrorMessage = "Only capital letters and numbers are allowed.")] [StringLength(64, MinimumLength = 64, ErrorMessage = "The SHA-256 hash must be exactly 64 characters.")] - public string PassportSha256 { get; set; } + public string PassportSha256 + { + get => _passportSha256; + set => _passportSha256 = value?.ToUpper(); + } + + private string _proofOfNinSha256; + [RegularExpression("^[A-F0-9]*$", ErrorMessage = "Only capital letters and numbers are allowed.")] [StringLength(64, MinimumLength = 64, ErrorMessage = "The SHA-256 hash must be exactly 64 characters.")] - public string ProofOfNinSha256 { get; set; } + public string ProofOfNinSha256 + { + get => _proofOfNinSha256; + set => _proofOfNinSha256 = value?.ToUpper(); + } + private string _birthCertificateSha256; + + [RegularExpression("^[A-F0-9]*$", ErrorMessage = "Only capital letters and numbers are allowed.")] [StringLength(64, MinimumLength = 64, ErrorMessage = "The SHA-256 hash must be exactly 64 characters.")] - public string BirthCertificateSha256 { get; set; } + public string BirthCertificateSha256 + { + get => _birthCertificateSha256; + set => _birthCertificateSha256 = value?.ToUpper(); + } } public class EncryptedCitizenshipData diff --git a/src/BolWallet/Models/GenericHashTableForm.cs b/src/BolWallet/Models/GenericHashTableForm.cs index 869b76d..777ee7f 100644 --- a/src/BolWallet/Models/GenericHashTableForm.cs +++ b/src/BolWallet/Models/GenericHashTableForm.cs @@ -1,4 +1,6 @@ -namespace BolWallet.Models +using System.ComponentModel.DataAnnotations; + +namespace BolWallet.Models { public partial class GenericHashTableForm : ObservableObject { @@ -13,5 +15,68 @@ public partial class GenericHashTableForm : ObservableObject public string PersonalVoice { get; set; } public string ProofOfCommunication { get; set; } public string ProofOfResidence { get; set; } + } + + public class GenericSHA256TableForm : ObservableObject + { + private string _drivingLicense; + + [RegularExpression("^[A-F0-9]*$", ErrorMessage = "Only capital letters and numbers are allowed.")] + [StringLength(64, MinimumLength = 64, ErrorMessage = "The SHA-256 hash must be exactly 64 characters.")] + public string DrivingLicense + { + get => _drivingLicense; + set => _drivingLicense = value?.ToUpper(); + } + + private string _otherIdentity; + + [RegularExpression("^[A-F0-9]*$", ErrorMessage = "Only capital letters and numbers are allowed.")] + [StringLength(64, MinimumLength = 64, ErrorMessage = "The SHA-256 hash must be exactly 64 characters.")] + public string OtherIdentity + { + get => _otherIdentity; + set => _otherIdentity = value?.ToUpper(); + } + + private string _facePhoto; + + [RegularExpression("^[A-F0-9]*$", ErrorMessage = "Only capital letters and numbers are allowed.")] + [StringLength(64, MinimumLength = 64, ErrorMessage = "The SHA-256 hash must be exactly 64 characters.")] + public string FacePhoto + { + get => _facePhoto; + set => _facePhoto = value?.ToUpper(); + } + + private string _personalVoice; + + [RegularExpression("^[A-F0-9]*$", ErrorMessage = "Only capital letters and numbers are allowed.")] + [StringLength(64, MinimumLength = 64, ErrorMessage = "The SHA-256 hash must be exactly 64 characters.")] + public string PersonalVoice + { + get => _personalVoice; + set => _personalVoice = value?.ToUpper(); + } + + private string _proofOfCommunication; + + [RegularExpression("^[A-F0-9]*$", ErrorMessage = "Only capital letters and numbers are allowed.")] + [StringLength(64, MinimumLength = 64, ErrorMessage = "The SHA-256 hash must be exactly 64 characters.")] + public string ProofOfCommunication + { + get => _proofOfCommunication; + set => _proofOfCommunication = value?.ToUpper(); + } + + private string _proofOfResidence; + + [RegularExpression("^[A-F0-9]*$", ErrorMessage = "Only capital letters and numbers are allowed.")] + [StringLength(64, MinimumLength = 64, ErrorMessage = "The SHA-256 hash must be exactly 64 characters.")] + public string ProofOfResidence + { + get => _proofOfResidence; + set => _proofOfResidence = value?.ToUpper(); + } } } diff --git a/src/BolWallet/Models/Messages/WalletCreatedMessage.cs b/src/BolWallet/Models/Messages/WalletCreatedMessage.cs new file mode 100644 index 0000000..67d695c --- /dev/null +++ b/src/BolWallet/Models/Messages/WalletCreatedMessage.cs @@ -0,0 +1,3 @@ +namespace BolWallet.Models.Messages; + +public record WalletCreatedMessage; diff --git a/src/BolWallet/Pages/CreateEdiPage.razor b/src/BolWallet/Pages/CreateEdiPage.razor index 2bb0923..9feefcb 100644 --- a/src/BolWallet/Pages/CreateEdiPage.razor +++ b/src/BolWallet/Pages/CreateEdiPage.razor @@ -11,32 +11,91 @@ - + + + @if (ViewModel.IsSha256InputMode) + { - - @edi.Item4 - @if (edi.Item1 == "PersonalVoice") - { - - - } - else - { - - - - } - + + + + + + + + + + + + + + + + +
+ Submit +
+
+
+
-
- -
- Submit -
-
+ + } + else + { + + + + @edi.Item4 + @if (edi.Item1 == "PersonalVoice") + { + + + } + else + { + + + + } + + + + +
+ Submit +
+
+ }
@if (ViewModel.IsRecording) @@ -54,7 +113,7 @@ .text-center { text-align: center; } - + .recording-overlay { position: fixed; top: 0; @@ -67,7 +126,7 @@ align-items: center; justify-content: center; } - + .recording-dialog { background-color: white; padding: 20px; @@ -78,6 +137,7 @@ } + @code { CreateEdiViewModel createEdiViewModel; @@ -112,8 +172,15 @@ ViewModel.IsLoading = true; StateHasChanged(); }); - - await createEdiViewModel.SubmitCommand.ExecuteAsync(null); + + if (ViewModel.IsSha256InputMode) + { + await createEdiViewModel.SubmitHashFormCommand.ExecuteAsync(null); + } + else + { + await createEdiViewModel.SubmitCommand.ExecuteAsync(null); + } await InvokeAsync(() => { @@ -149,7 +216,7 @@ ViewModel.IsLoading = true; StateHasChanged(); }); - + await UpdateIdentificationDocumentsList(property); } catch (Exception e) @@ -179,7 +246,7 @@ ViewModel.IsLoading = true; StateHasChanged(); }); - + await UpdateIdentificationDocumentsList(property); } catch (Exception e) diff --git a/src/BolWallet/Pages/EcryptedCitizenshipPage.razor b/src/BolWallet/Pages/EcryptedCitizenshipPage.razor index e0b7b7c..e634a89 100644 --- a/src/BolWallet/Pages/EcryptedCitizenshipPage.razor +++ b/src/BolWallet/Pages/EcryptedCitizenshipPage.razor @@ -339,13 +339,12 @@ { var submittedForm = context.Model as EncryptedCitizenshipForm; - if(false){ - await ViewModel.SubmitFormCommand.ExecuteAsync(submittedForm); - + if (ViewModel.IsSha256InputMode) + { + await ViewModel.SubmitHashFormCommand.ExecuteAsync(submittedForm); } else{ - await ViewModel.SubmitHashFormCommand.ExecuteAsync(submittedForm); - + await ViewModel.SubmitFormCommand.ExecuteAsync(submittedForm); } } catch (Exception ex) diff --git a/src/BolWallet/Pages/WalletCreationInfo.razor b/src/BolWallet/Pages/WalletCreationInfo.razor index 64e394e..2eeef63 100644 --- a/src/BolWallet/Pages/WalletCreationInfo.razor +++ b/src/BolWallet/Pages/WalletCreationInfo.razor @@ -30,10 +30,10 @@ - + - + diff --git a/src/BolWallet/Platforms/MacCatalyst/Info.plist b/src/BolWallet/Platforms/MacCatalyst/Info.plist index cdf745a..6ea50bd 100644 --- a/src/BolWallet/Platforms/MacCatalyst/Info.plist +++ b/src/BolWallet/Platforms/MacCatalyst/Info.plist @@ -31,9 +31,9 @@ processing CFBundleVersion - 2024.1004.1800 + 2024.1009.1430 CFBundleShortVersionString - 2.1.0 + 2.2.0 CFBundleDevelopmentRegion en NSHumanReadableCopyright diff --git a/src/BolWallet/Platforms/iOS/Info.plist b/src/BolWallet/Platforms/iOS/Info.plist index ca3f6c0..fb14a36 100644 --- a/src/BolWallet/Platforms/iOS/Info.plist +++ b/src/BolWallet/Platforms/iOS/Info.plist @@ -35,9 +35,9 @@ NSPhotoLibraryUsageDescription The app can use the photo library to select photos from your library and use them when creating a new wallet. CFBundleVersion - 2024.1004.1800 + 2024.1009.1430 CFBundleShortVersionString - 2.1.0 + 2.2.0 CFBundleDevelopmentRegion en NSHumanReadableCopyright diff --git a/src/BolWallet/Services/BolServiceFactory.cs b/src/BolWallet/Services/BolServiceFactory.cs index de8b7e9..91c4feb 100644 --- a/src/BolWallet/Services/BolServiceFactory.cs +++ b/src/BolWallet/Services/BolServiceFactory.cs @@ -6,7 +6,7 @@ namespace BolWallet.Services; -public class BolServiceFactory : IRecipient +public class BolServiceFactory : IRecipient, IRecipient { private IServiceScope _serviceScope; private readonly IServiceScopeFactory _serviceScopeFactory; @@ -14,11 +14,13 @@ public class BolServiceFactory : IRecipient public BolServiceFactory( IServiceScopeFactory serviceScopeFactory, + IMessenger messenger, ILogger logger) { _serviceScopeFactory = serviceScopeFactory; _logger = logger; - WeakReferenceMessenger.Default.Register(this); + messenger.Register(this); + messenger.Register(this); } public IBolService Create() @@ -33,4 +35,11 @@ public void Receive(WalletClosedMessage message) _serviceScope?.Dispose(); _serviceScope = null; } + + public void Receive(WalletCreatedMessage message) + { + _logger.LogInformation("Received {Message}, disposing BOL services so new instances get access to new wallet...", message.GetType().Name); + _serviceScope?.Dispose(); + _serviceScope = null; + } } diff --git a/src/BolWallet/ViewModels/CreateEdiViewModel.cs b/src/BolWallet/ViewModels/CreateEdiViewModel.cs index 59374dc..1e1fbd5 100644 --- a/src/BolWallet/ViewModels/CreateEdiViewModel.cs +++ b/src/BolWallet/ViewModels/CreateEdiViewModel.cs @@ -30,6 +30,7 @@ public CreateEdiViewModel( _mediaService = mediaService; _certificationMatrix = new CertificationMatrix { Hashes = new GenericHashTable() }; GenericHashTableForm = new GenericHashTableForm(); + GenericSHA256TableForm = new GenericSHA256TableForm(); EdiFiles = new GenericHashTableFiles(); } @@ -37,10 +38,19 @@ public CreateEdiViewModel( [ObservableProperty] private GenericHashTableForm _genericHashTableForm; + [ObservableProperty] private GenericSHA256TableForm _genericSHA256TableForm; + [ObservableProperty] private bool _isLoading = false; [ObservableProperty] private bool _isRecording = false; + [ObservableProperty] private bool _isSha256InputMode; + + public void OnKnownHashInputModeChange(bool newValue) + { + IsSha256InputMode = newValue; + } + [RelayCommand] private async Task PickFileAsync(string propertyName) { @@ -160,6 +170,19 @@ private async Task Submit() } } + [RelayCommand] + private async Task SubmitHashForm() + { + _certificationMatrix.Hashes.FacePhoto = GenericSHA256TableForm.FacePhoto?.ToUpper() ?? Constants.DefaultHash; + _certificationMatrix.Hashes.PersonalVoice = GenericSHA256TableForm.PersonalVoice?.ToUpper() ?? Constants.DefaultHash; + _certificationMatrix.Hashes.DrivingLicense = GenericSHA256TableForm.DrivingLicense?.ToUpper() ?? Constants.DefaultHash; + _certificationMatrix.Hashes.OtherIdentity = GenericSHA256TableForm.OtherIdentity?.ToUpper() ?? Constants.DefaultHash; + _certificationMatrix.Hashes.ProofOfCommunication = GenericSHA256TableForm.ProofOfCommunication?.ToUpper() ?? Constants.DefaultHash; + _certificationMatrix.Hashes.ProofOfResidence = GenericSHA256TableForm.ProofOfResidence?.ToUpper() ?? Constants.DefaultHash; + + await Submit(); + } + private async Task PathPerImport(PropertyInfo propertyNameInfo, FileResult fileResult) { if (fileResult == null) return; diff --git a/src/BolWallet/ViewModels/GenerateWalletWithPasswordViewModel.cs b/src/BolWallet/ViewModels/GenerateWalletWithPasswordViewModel.cs index 1a54e8a..c2c4af9 100644 --- a/src/BolWallet/ViewModels/GenerateWalletWithPasswordViewModel.cs +++ b/src/BolWallet/ViewModels/GenerateWalletWithPasswordViewModel.cs @@ -1,8 +1,6 @@ using Bol.Core.Abstractions; -using Bol.Cryptography; using CommunityToolkit.Maui.Alerts; -using CommunityToolkit.Maui.Storage; -using System.Text; +using CommunityToolkit.Mvvm.Messaging; namespace BolWallet.ViewModels; @@ -12,19 +10,22 @@ public partial class GenerateWalletWithPasswordViewModel : BaseViewModel private readonly ISecureRepository _secureRepository; private readonly IFileDownloadService _fileDownloadService; private readonly IDeviceDisplay _deviceDisplay; + private readonly IMessenger _messenger; public GenerateWalletWithPasswordViewModel( INavigationService navigationService, IWalletService walletService, ISecureRepository secureRepository, IFileDownloadService fileDownloadService, - IDeviceDisplay deviceDisplay) + IDeviceDisplay deviceDisplay, + IMessenger messenger) : base(navigationService) { _walletService = walletService; _secureRepository = secureRepository; _fileDownloadService = fileDownloadService; _deviceDisplay = deviceDisplay; + _messenger = messenger; } [ObservableProperty] @@ -76,6 +77,8 @@ private async Task Submit() await DownloadWalletAsync(bolWallet); + _messenger.Send(Constants.WalletCreatedMessage); + await NavigationService.NavigateTo(); } catch (Exception ex) diff --git a/src/BolWallet/ViewModels/SubmitCitizenshipViewModel.cs b/src/BolWallet/ViewModels/SubmitCitizenshipViewModel.cs index fc0a6e3..02e0c02 100644 --- a/src/BolWallet/ViewModels/SubmitCitizenshipViewModel.cs +++ b/src/BolWallet/ViewModels/SubmitCitizenshipViewModel.cs @@ -318,11 +318,11 @@ await Task.Run((Func)(async () => var citizenshipHashes = new CitizenshipHashTable { - IdentityCard = form.IdentityCardSha256?.ToUpper() ?? null, - IdentityCardBack = form.IdentityCardBackSha256?.ToUpper() ?? null, - Passport = form.PassportSha256?.ToUpper() ?? null, - ProofOfNin = form.ProofOfNinSha256?.ToUpper() ?? null, - BirthCertificate = form.BirthCertificateSha256?.ToUpper() ?? null + IdentityCard = form.IdentityCardSha256?.ToUpper() ?? Constants.DefaultHash, + IdentityCardBack = form.IdentityCardBackSha256?.ToUpper() ?? Constants.DefaultHash, + Passport = form.PassportSha256?.ToUpper() ?? Constants.DefaultHash, + ProofOfNin = form.ProofOfNinSha256?.ToUpper() ?? Constants.DefaultHash, + BirthCertificate = form.BirthCertificateSha256?.ToUpper() ?? Constants.DefaultHash }; var encryptedCitizenshipData = new EncryptedCitizenshipData