diff --git a/MauiPasswordVault/App.xaml.cs b/MauiPasswordVault/App.xaml.cs
index c4a9f19..d1a3a71 100644
--- a/MauiPasswordVault/App.xaml.cs
+++ b/MauiPasswordVault/App.xaml.cs
@@ -1,4 +1,7 @@
using MauiPasswordVault.View;
+using Microsoft.Maui.Hosting;
+using System.Globalization;
+using System.Text.RegularExpressions;
namespace MauiPasswordVault
{
@@ -8,9 +11,17 @@ public App(SearchPage searchPage)
{
if (Application.Current != null)
Application.Current.UserAppTheme = AppTheme.Dark;
-
InitializeComponent();
+#if DEBUG
+ Resources.MergedDictionaries.Add(new MauiPasswordVault.Resources.Lang.en());
+#else
+ if (Thread.CurrentThread.CurrentUICulture.IetfLanguageTag == "fr-FR")
+ Resources.MergedDictionaries.Add(new MauiPasswordVault.Resources.Lang.fr());
+ else
+ Resources.MergedDictionaries.Add(new MauiPasswordVault.Resources.Lang.en());
+#endif
+
MainPage = new NavigationPage(searchPage);
}
}
diff --git a/MauiPasswordVault/MauiPasswordVault.csproj b/MauiPasswordVault/MauiPasswordVault.csproj
index 982317f..9706c53 100644
--- a/MauiPasswordVault/MauiPasswordVault.csproj
+++ b/MauiPasswordVault/MauiPasswordVault.csproj
@@ -14,19 +14,19 @@
Password Vault
- com.companyname.mauipasswordvault
+ com.github.vault
8409360f-6d94-4dc3-a09f-38b31006a68d
- 3.0.0.0
+ 3.3.0.0
3
21.0
10.0.17763.0
10.0.17763.0
- 3.0.0.0
- 3.0.0.0
- 3.0.0.0
+ 3.3.0.0
+ 3.3.0.0
+ 3.3.0.0
False
True
False
@@ -42,8 +42,8 @@
-
-
+
+
@@ -57,12 +57,15 @@
-
-
-
+
+
+
+
+
+
@@ -76,6 +79,12 @@
+
+ MSBuild:Compile
+
+
+ MSBuild:Compile
+
MSBuild:Compile
diff --git a/MauiPasswordVault/MauiProgram.cs b/MauiPasswordVault/MauiProgram.cs
index 5bebc45..c1aa0c5 100644
--- a/MauiPasswordVault/MauiProgram.cs
+++ b/MauiPasswordVault/MauiProgram.cs
@@ -1,8 +1,13 @@
-using MauiPasswordVault.Service;
+using CommunityToolkit.Maui;
+using MauiPasswordVault.Service;
using MauiPasswordVault.View;
using MauiPasswordVault.ViewModel;
using Microsoft.Extensions.Logging;
+using NLog.Extensions.Logging;
+using NLog;
using VaultCore;
+using NLog.Config;
+using NLog.Targets;
namespace MauiPasswordVault;
@@ -13,6 +18,7 @@ public static MauiApp CreateMauiApp()
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp()
+ .UseMauiCommunityToolkit()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
@@ -22,6 +28,26 @@ public static MauiApp CreateMauiApp()
fonts.AddFont("AwesomeSolid.otf", "AwesomeSolid");
});
+ #region Logger
+ LoggingConfiguration logConfig = new();
+
+ FileTarget fileTarget = new()
+ {
+ FileName = typeof(MauiProgram).FullName + ".log",
+ Layout = @"${longdate} [${uppercase:${level}}] ${logger} - ${message} ${exception:format=tostring}"
+ };
+
+ LoggingRule fileRule = new("*", NLog.LogLevel.Info, fileTarget);
+ logConfig.LoggingRules.Add(fileRule);
+ logConfig.AddTarget("logfile", fileTarget);
+
+ builder.Logging.ClearProviders();
+ builder.Logging.AddNLog(logConfig);
+#if DEBUG
+ builder.Logging.AddDebug();
+#endif
+ #endregion
+
builder.Services.AddSingleton();
builder.Services.AddSingleton();
builder.Services.AddSingleton();
@@ -37,9 +63,6 @@ public static MauiApp CreateMauiApp()
builder.Services.AddTransient();
builder.Services.AddTransient();
-#if DEBUG
- builder.Logging.AddDebug();
-#endif
return builder.Build();
}
diff --git a/MauiPasswordVault/Platforms/Android/MainActivity.cs b/MauiPasswordVault/Platforms/Android/MainActivity.cs
index 9bd089d..e907df5 100644
--- a/MauiPasswordVault/Platforms/Android/MainActivity.cs
+++ b/MauiPasswordVault/Platforms/Android/MainActivity.cs
@@ -4,7 +4,7 @@
namespace MauiPasswordVault
{
- [Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
+ [Activity(Theme = "@style/MyAppTheme", MainLauncher = true, ScreenOrientation = ScreenOrientation.Sensor, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
public class MainActivity : MauiAppCompatActivity
{
}
diff --git a/MauiPasswordVault/Platforms/Android/Resources/values/colors.xml b/MauiPasswordVault/Platforms/Android/Resources/values/colors.xml
index c04d749..4a65b9c 100644
--- a/MauiPasswordVault/Platforms/Android/Resources/values/colors.xml
+++ b/MauiPasswordVault/Platforms/Android/Resources/values/colors.xml
@@ -1,6 +1,7 @@
- #512BD4
+ #A265BE
#2B0B98
- #2B0B98
+ #A265BE
+ #000000
\ No newline at end of file
diff --git a/MauiPasswordVault/Platforms/Android/Resources/values/style.xml b/MauiPasswordVault/Platforms/Android/Resources/values/style.xml
new file mode 100644
index 0000000..4d4e813
--- /dev/null
+++ b/MauiPasswordVault/Platforms/Android/Resources/values/style.xml
@@ -0,0 +1,9 @@
+
+
+
+
\ No newline at end of file
diff --git a/MauiPasswordVault/Resources/Images/dimport.png b/MauiPasswordVault/Resources/Images/dimport.png
new file mode 100644
index 0000000..401cd4b
Binary files /dev/null and b/MauiPasswordVault/Resources/Images/dimport.png differ
diff --git a/MauiPasswordVault/Resources/Images/dotnet_bot.svg b/MauiPasswordVault/Resources/Images/dotnet_bot.svg
deleted file mode 100644
index abfaff2..0000000
--- a/MauiPasswordVault/Resources/Images/dotnet_bot.svg
+++ /dev/null
@@ -1,93 +0,0 @@
-
diff --git a/MauiPasswordVault/Resources/Images/home.svg b/MauiPasswordVault/Resources/Images/home.svg
deleted file mode 100644
index ccee5c3..0000000
--- a/MauiPasswordVault/Resources/Images/home.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/MauiPasswordVault/Resources/Images/information.svg b/MauiPasswordVault/Resources/Images/information.svg
deleted file mode 100644
index aa62747..0000000
--- a/MauiPasswordVault/Resources/Images/information.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/MauiPasswordVault/Resources/Images/search.png b/MauiPasswordVault/Resources/Images/search.png
new file mode 100644
index 0000000..4e8b251
Binary files /dev/null and b/MauiPasswordVault/Resources/Images/search.png differ
diff --git a/MauiPasswordVault/Resources/Images/show.png b/MauiPasswordVault/Resources/Images/show.png
new file mode 100644
index 0000000..992c301
Binary files /dev/null and b/MauiPasswordVault/Resources/Images/show.png differ
diff --git a/MauiPasswordVault/Resources/Images/splash.svg b/MauiPasswordVault/Resources/Images/splash.svg
new file mode 100644
index 0000000..cbee645
--- /dev/null
+++ b/MauiPasswordVault/Resources/Images/splash.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/MauiPasswordVault/Resources/Lang/en.xaml b/MauiPasswordVault/Resources/Lang/en.xaml
new file mode 100644
index 0000000..3282790
--- /dev/null
+++ b/MauiPasswordVault/Resources/Lang/en.xaml
@@ -0,0 +1,17 @@
+
+
+
+ Unlock
+ Password
+ Ok
+ Initialize
+ Your password
+ Confirm it
+ Search
+ Get passwords from internet
+ URL
+
+
\ No newline at end of file
diff --git a/MauiPasswordVault/Resources/Lang/en.xaml.cs b/MauiPasswordVault/Resources/Lang/en.xaml.cs
new file mode 100644
index 0000000..c3a5891
--- /dev/null
+++ b/MauiPasswordVault/Resources/Lang/en.xaml.cs
@@ -0,0 +1,9 @@
+namespace MauiPasswordVault.Resources.Lang;
+
+public partial class en : ResourceDictionary
+{
+ public en()
+ {
+ InitializeComponent();
+ }
+}
\ No newline at end of file
diff --git a/MauiPasswordVault/Resources/Lang/fr.xaml b/MauiPasswordVault/Resources/Lang/fr.xaml
new file mode 100644
index 0000000..cc80d65
--- /dev/null
+++ b/MauiPasswordVault/Resources/Lang/fr.xaml
@@ -0,0 +1,17 @@
+
+
+
+ Déverrouiller
+ Mot de passe
+ Ok
+ Initialiser
+ Votre mot de passe
+ Confirmez le mot de passe
+ Rechercher
+ Mise à jour depuis le net
+ URL
+
+
\ No newline at end of file
diff --git a/MauiPasswordVault/Resources/Lang/fr.xaml.cs b/MauiPasswordVault/Resources/Lang/fr.xaml.cs
new file mode 100644
index 0000000..ff5ff26
--- /dev/null
+++ b/MauiPasswordVault/Resources/Lang/fr.xaml.cs
@@ -0,0 +1,9 @@
+namespace MauiPasswordVault.Resources.Lang;
+
+public partial class fr : ResourceDictionary
+{
+ public fr()
+ {
+ InitializeComponent();
+ }
+}
\ No newline at end of file
diff --git a/MauiPasswordVault/Resources/Styles/Colors.xaml b/MauiPasswordVault/Resources/Styles/Colors.xaml
index 245758b..5e4bac6 100644
--- a/MauiPasswordVault/Resources/Styles/Colors.xaml
+++ b/MauiPasswordVault/Resources/Styles/Colors.xaml
@@ -3,7 +3,7 @@
-
+
#512BD4
#DFD8F7
#2B0B98
diff --git a/MauiPasswordVault/View/CheckPage.xaml b/MauiPasswordVault/View/CheckPage.xaml
index f78630c..9373992 100644
--- a/MauiPasswordVault/View/CheckPage.xaml
+++ b/MauiPasswordVault/View/CheckPage.xaml
@@ -1,54 +1,37 @@
+ x:Class="MauiPasswordVault.View.CheckPage">
+ Padding="30,30"
+ VerticalOptions="FillAndExpand">
+ HeightRequest="100"
+ HorizontalOptions="Start" />
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/MauiPasswordVault/View/InitPage.xaml b/MauiPasswordVault/View/InitPage.xaml
index a5c1d5c..f2389e3 100644
--- a/MauiPasswordVault/View/InitPage.xaml
+++ b/MauiPasswordVault/View/InitPage.xaml
@@ -1,31 +1,30 @@

-
+
+ Padding="30,30"
+ VerticalOptions="FillAndExpand">
+ Source="logo.png"
+ HeightRequest="100"
+ HorizontalOptions="Start" />
-
-
-
-
+
+
+
diff --git a/MauiPasswordVault/View/SearchPage.xaml b/MauiPasswordVault/View/SearchPage.xaml
index 46a7431..2a289d6 100644
--- a/MauiPasswordVault/View/SearchPage.xaml
+++ b/MauiPasswordVault/View/SearchPage.xaml
@@ -2,13 +2,49 @@
-
-
-
-
-
+ xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
+ Title="Password vault"
+ Loaded="ContentPage_Loaded">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/MauiPasswordVault/View/SearchPage.xaml.cs b/MauiPasswordVault/View/SearchPage.xaml.cs
index cb260ce..efbffc1 100644
--- a/MauiPasswordVault/View/SearchPage.xaml.cs
+++ b/MauiPasswordVault/View/SearchPage.xaml.cs
@@ -20,15 +20,16 @@ protected async override void OnAppearing()
{
try
{
- bool isInitialized = ((SearchViewModel)BindingContext).IsInitialized();
- if (!isInitialized)
+ if (!((SearchViewModel)BindingContext).IsInitialized())
+ {
await navigationService.NavigateToPage();
-
- if (isInitialized && !((SearchViewModel)BindingContext).IsUnlock())
- await navigationService.NavigateToPage();
-
- if (isInitialized && ((SearchViewModel)BindingContext).IsUnlock())
- ((SearchViewModel)BindingContext).Load();
+ return;
+ }
+ else
+ {
+ if (!((SearchViewModel)BindingContext).IsUnlock())
+ await navigationService.NavigateToPage();
+ }
}
catch (Exception exception)
{
@@ -38,4 +39,11 @@ protected async override void OnAppearing()
await this.navigationService.NavigateToPage();
}
}
+
+ private void ContentPage_Loaded(object sender, EventArgs e)
+ {
+#pragma warning disable CS4014 // Dans la mesure où cet appel n'est pas attendu, l'exécution de la méthode actuelle continue avant la fin de l'appel
+ ((SearchViewModel)BindingContext).LoadAsync();
+#pragma warning restore CS4014 // Dans la mesure où cet appel n'est pas attendu, l'exécution de la méthode actuelle continue avant la fin de l'appel
+ }
}
\ No newline at end of file
diff --git a/MauiPasswordVault/ViewModel/CheckViewModel.cs b/MauiPasswordVault/ViewModel/CheckViewModel.cs
index ec781d8..d85692b 100644
--- a/MauiPasswordVault/ViewModel/CheckViewModel.cs
+++ b/MauiPasswordVault/ViewModel/CheckViewModel.cs
@@ -1,5 +1,6 @@
using MauiPasswordVault.Service;
using MauiPasswordVault.View;
+using Microsoft.Extensions.Logging;
using System.Windows.Input;
using VaultCore;
@@ -10,13 +11,15 @@ public class CheckViewModel
private readonly NavigationService navigationService;
private readonly ErrorService errorService;
private readonly MyVault vault;
+ private readonly ILogger logger;
private String vaultKey = null!;
- public CheckViewModel(NavigationService navigationService, ErrorService errorService, MyVault vault)
+ public CheckViewModel(NavigationService navigationService, ErrorService errorService, MyVault vault, ILogger logger)
{
this.navigationService = navigationService;
this.vault = vault;
this.errorService = errorService;
+ this.logger = logger;
CheckCommand = new Command(
execute: () =>
@@ -24,7 +27,7 @@ public CheckViewModel(NavigationService navigationService, ErrorService errorSer
try
{
if (vault.CheckVaultKey(VaultKey))
- this.navigationService.NavigateBack();
+ this.navigationService.NavigateToPage();
else
{
this.errorService.LastErrorMessage = "Bad password vault";
@@ -34,6 +37,7 @@ public CheckViewModel(NavigationService navigationService, ErrorService errorSer
}
catch (Exception exception)
{
+ logger.LogError(exception, nameof(CheckCommand) + " failed");
this.errorService.LastErrorMessage = exception.Message;
this.errorService.LastErrorFull = exception.ToString();
this.errorService.CriticalError = true;
@@ -48,6 +52,7 @@ public CheckViewModel(NavigationService navigationService, ErrorService errorSer
}
catch (Exception exception)
{
+ logger.LogError(exception, nameof(CheckCommand) + " failed");
this.errorService.LastErrorMessage = exception.Message;
this.errorService.LastErrorFull = exception.ToString();
this.errorService.CriticalError = true;
diff --git a/MauiPasswordVault/ViewModel/ErrorViewModel.cs b/MauiPasswordVault/ViewModel/ErrorViewModel.cs
index a4c24c8..951832f 100644
--- a/MauiPasswordVault/ViewModel/ErrorViewModel.cs
+++ b/MauiPasswordVault/ViewModel/ErrorViewModel.cs
@@ -1,4 +1,5 @@
using MauiPasswordVault.Service;
+using Microsoft.Extensions.Logging;
using System.Windows.Input;
namespace MauiPasswordVault.ViewModel;
@@ -7,19 +8,28 @@ public class ErrorViewModel
{
private readonly NavigationService navigationService;
private readonly ErrorService errorService;
+ private readonly ILogger logger;
- public ErrorViewModel(NavigationService navigationService, ErrorService errorService)
+ public ErrorViewModel(NavigationService navigationService, ErrorService errorService, ILogger logger)
{
this.navigationService = navigationService;
this.errorService = errorService;
+ this.logger = logger;
AcceptCommand = new Command(
execute: () =>
{
- if (errorService.CriticalError)
- Application.Current?.Quit();
- else
- this.navigationService.NavigateBack();
+ try
+ {
+ if (errorService.CriticalError)
+ Application.Current?.Quit();
+ else
+ this.navigationService.NavigateBack();
+ }
+ catch (Exception except)
+ {
+ logger.LogCritical(except, nameof(AcceptCommand) + " failed");
+ }
},
canExecute: () =>
{
diff --git a/MauiPasswordVault/ViewModel/InitViewModel.cs b/MauiPasswordVault/ViewModel/InitViewModel.cs
index 6404aed..627600c 100644
--- a/MauiPasswordVault/ViewModel/InitViewModel.cs
+++ b/MauiPasswordVault/ViewModel/InitViewModel.cs
@@ -1,5 +1,6 @@
using MauiPasswordVault.Service;
using MauiPasswordVault.View;
+using Microsoft.Extensions.Logging;
using System.Windows.Input;
using VaultCore;
@@ -10,14 +11,16 @@ public class InitViewModel
private readonly NavigationService navigationService;
private readonly ErrorService errorService;
private readonly MyVault vault;
+ private readonly ILogger logger;
private String newKey = null!;
private String chkKey = null!;
- public InitViewModel(NavigationService navigationService, ErrorService errorService, MyVault vault)
+ public InitViewModel(NavigationService navigationService, ErrorService errorService, MyVault vault, ILogger logger)
{
this.navigationService = navigationService;
this.errorService = errorService;
this.vault = vault;
+ this.logger = logger;
InitCommand = new Command(
execute: () =>
@@ -25,7 +28,7 @@ public InitViewModel(NavigationService navigationService, ErrorService errorServ
try
{
if (this.vault.Initialize(NewVaultKey))
- this.navigationService.NavigateBack();
+ this.navigationService.NavigateToPage();
else
{
this.errorService.LastErrorMessage = "Can't initialize vault";
@@ -35,6 +38,7 @@ public InitViewModel(NavigationService navigationService, ErrorService errorServ
}
catch (Exception exception)
{
+ logger.LogError(exception, nameof(InitCommand) + " failed");
this.errorService.LastErrorMessage = exception.Message;
this.errorService.LastErrorFull = exception.ToString();
this.errorService.CriticalError = true;
@@ -49,6 +53,7 @@ public InitViewModel(NavigationService navigationService, ErrorService errorServ
}
catch (Exception exception)
{
+ logger.LogError(exception, nameof(InitCommand) + " failed");
this.errorService.LastErrorMessage = exception.Message;
this.errorService.LastErrorFull = exception.ToString();
this.errorService.CriticalError = true;
diff --git a/MauiPasswordVault/ViewModel/SearchViewModel.cs b/MauiPasswordVault/ViewModel/SearchViewModel.cs
index 3650b89..09bf239 100644
--- a/MauiPasswordVault/ViewModel/SearchViewModel.cs
+++ b/MauiPasswordVault/ViewModel/SearchViewModel.cs
@@ -1,25 +1,234 @@
-using VaultCore;
+using CommunityToolkit.Mvvm.Input;
+using MauiPasswordVault.Service;
+using MauiPasswordVault.View;
+using Microsoft.Extensions.Logging;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using VaultCore;
+using VaultCore.Models;
namespace MauiPasswordVault.ViewModel;
-public class SearchViewModel
+public partial class SearchViewModel : INotifyPropertyChanged
{
- private readonly MyVault vault;
- public SearchViewModel(MyVault vault)
+ public SearchViewModel(NavigationService navigationService, ErrorService errorService, MyVault vault, ILogger logger)
{
+ this.navigationService = navigationService;
+ this.errorService = errorService;
this.vault = vault;
+ this.logger = logger;
}
- public MyVault Vault { get => vault; }
+ public event PropertyChangedEventHandler? PropertyChanged;
- public bool IsInitialized() => vault.IsInitialized();
- public bool IsUnlock() => vault.IsUnlock();
- public void Load()
+ #region Private data
+ private const String URL = "UPDATE_URL";
+ private readonly object vaultLock = new object();
+ private readonly NavigationService navigationService;
+ private readonly ErrorService errorService;
+ private readonly MyVault vault;
+ private readonly ILogger logger;
+ private String url = Preferences.Default.Get(SearchViewModel.URL, "");
+ private bool inProgress = false;
+ private bool isLoading = false;
+ private String searchEntry = "";
+ private ObservableCollection passwords = new ObservableCollection();
+ #endregion
+
+ #region Command
+ [RelayCommand(FlowExceptionsToTaskScheduler = true, CanExecute = nameof(CanUpdate))]
+ public async Task UpdateAsync()
+ {
+ try
+ {
+ InProgress = true;
+ Preferences.Default.Set(URL, url);
+ await Task.Factory.StartNew(() =>
+ {
+ lock (vaultLock)
+ {
+ vault.Download(url);
+ }
+ });
+ }
+ catch (Exception exception)
+ {
+ logger.LogError(exception, nameof(UpdateAsync) + " failed");
+ this.errorService.LastErrorMessage = exception.Message;
+ this.errorService.LastErrorFull = exception.ToString();
+ this.errorService.CriticalError = false;
+#pragma warning disable CS4014 // Dans la mesure où cet appel n'est pas attendu, l'exécution de la méthode actuelle continue avant la fin de l'appel
+ this.navigationService.NavigateToPage();
+#pragma warning restore CS4014 // Dans la mesure où cet appel n'est pas attendu, l'exécution de la méthode actuelle continue avant la fin de l'appel
+ }
+ finally
+ {
+ InProgress = false;
+ }
+ }
+
+ private bool CanUpdate()
+ {
+ try
+ {
+ return (!String.IsNullOrEmpty(url));
+ }
+ catch (Exception exception)
+ {
+ logger.LogError(exception, nameof(CanUpdate) + " failed");
+ this.errorService.LastErrorMessage = exception.Message;
+ this.errorService.LastErrorFull = exception.ToString();
+ this.errorService.CriticalError = true;
+ this.navigationService.NavigateToPage();
+ }
+
+ return false;
+ }
+
+ [RelayCommand(FlowExceptionsToTaskScheduler = true)]
+ public async Task LoadAsync()
+ {
+ try
+ {
+ IsLoading = true;
+ await Task.Factory.StartNew(() =>
+ {
+ lock (vaultLock)
+ {
+ vault.Load();
+ }
+ });
+ }
+ catch (Exception exception)
+ {
+ logger.LogError(exception, nameof(LoadAsync) + " failed");
+ this.errorService.LastErrorMessage = exception.Message;
+ this.errorService.LastErrorFull = exception.ToString();
+ this.errorService.CriticalError = true;
+#pragma warning disable CS4014 // Dans la mesure où cet appel n'est pas attendu, l'exécution de la méthode actuelle continue avant la fin de l'appel
+ this.navigationService.NavigateToPage();
+#pragma warning restore CS4014 // Dans la mesure où cet appel n'est pas attendu, l'exécution de la méthode actuelle continue avant la fin de l'appel
+ }
+ finally
+ {
+ IsLoading = false;
+ }
+ }
+
+ [RelayCommand(FlowExceptionsToTaskScheduler = true, CanExecute = nameof(CanSearch))]
+ public async Task SearchAsync()
{
- vault.Load();
-#if DEBUG
- if(vault.Count == 0)
- vault.Add(new VaultCore.Models.MyPassword());
-#endif
+ try
+ {
+ IsLoading = true;
+ await Task.Factory.StartNew(() =>
+ {
+ ObservableCollection results = new ObservableCollection();
+
+ lock (vaultLock)
+ {
+ foreach (MyPassword myPassword in vault)
+ {
+ if (myPassword.ToStr().Contains(searchEntry))
+ results.Add(myPassword);
+ }
+ }
+
+ Passwords = results;
+ });
+ }
+ catch (Exception exception)
+ {
+ logger.LogError(exception, nameof(SearchAsync) + " failed");
+ this.errorService.LastErrorMessage = exception.Message;
+ this.errorService.LastErrorFull = exception.ToString();
+ this.errorService.CriticalError = false;
+#pragma warning disable CS4014 // Dans la mesure où cet appel n'est pas attendu, l'exécution de la méthode actuelle continue avant la fin de l'appel
+ this.navigationService.NavigateToPage();
+#pragma warning restore CS4014 // Dans la mesure où cet appel n'est pas attendu, l'exécution de la méthode actuelle continue avant la fin de l'appel
+ }
+ finally
+ {
+ IsLoading = false;
+ }
}
+
+ private bool CanSearch()
+ {
+ try
+ {
+ bool canSearch = (!String.IsNullOrEmpty(SearchEntry) && (SearchEntry.Length >= 3));
+ if (!canSearch)
+ Passwords = null!;
+ return canSearch;
+ }
+ catch (Exception exception)
+ {
+ logger.LogError(exception, nameof(CanSearch) + " failed");
+ this.errorService.LastErrorMessage = exception.Message;
+ this.errorService.LastErrorFull = exception.ToString();
+ this.errorService.CriticalError = true;
+ this.navigationService.NavigateToPage();
+ }
+
+ return false;
+ }
+ #endregion
+
+ #region Properties
+ public String Url
+ {
+ get { return url; }
+ set
+ {
+ url = value;
+ (UpdateCommand as Command)?.ChangeCanExecute();
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Url)));
+ }
+ }
+
+ public bool InProgress
+ {
+ get => inProgress;
+ set
+ {
+ inProgress = value;
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(InProgress)));
+ }
+ }
+
+ public bool IsLoading
+ {
+ get => isLoading;
+ set
+ {
+ isLoading = value;
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsLoading)));
+ }
+ }
+
+ public String SearchEntry
+ {
+ get => searchEntry;
+ set
+ {
+ searchEntry = value;
+ (SearchCommand as Command)?.ChangeCanExecute();
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SearchEntry)));
+ }
+ }
+
+ public ObservableCollection Passwords
+ {
+ get => passwords;
+ set
+ {
+ passwords = value;
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Passwords)));
+ }
+ }
+ #endregion
+
+ public bool IsInitialized() => vault.IsInitialized();
+ public bool IsUnlock() => vault.IsUnlock();
}
diff --git a/README.fr-fr.md b/README.fr-fr.md
index 5672b09..9057797 100644
--- a/README.fr-fr.md
+++ b/README.fr-fr.md
@@ -10,6 +10,7 @@ Coffre-fort de mots de passe avec import de mot de passe Firefox. Ce coffre-fort
* [Cryptage AES](https://fr.wikipedia.org/wiki/Advanced_Encryption_Standard) :key:
* Importer vos mots de passe depuis Firefox :earth_americas:
* Support multilingue (:clipperton_island:, :us:)
+* Compatible Android et Windows
# L'application en détails
@@ -21,15 +22,20 @@ Coffre-fort de mots de passe avec import de mot de passe Firefox. Ce coffre-fort
![](https://github.com/DevElkami/PasswordVault/blob/master/vault-pwd.png)
-3. Aperçu de l'application
+3. Aperçu de l'application (WinForm)
![](https://github.com/DevElkami/PasswordVault/blob/master/vault-add.png)
![](https://github.com/DevElkami/PasswordVault/blob/master/vault-import.png)
![](https://github.com/DevElkami/PasswordVault/blob/master/vault-main.png)
+3. Aperçu de l'application (MAUI)
+
+![](https://github.com/DevElkami/PasswordVault/blob/master/android-1.en.jpg)
+![](https://github.com/DevElkami/PasswordVault/blob/master/android-2.en.jpg)
+![](https://github.com/DevElkami/PasswordVault/blob/master/android-3.en.jpg)
-# Remerciements :pray:
+# Remerciements :pray:
> [NLog](https://github.com/NLog)
> [ReaLTaiizor](https://github.com/Taiizor/ReaLTaiizor)
diff --git a/README.md b/README.md
index 72fc01b..7a4adff 100644
--- a/README.md
+++ b/README.md
@@ -10,6 +10,7 @@ Personal password vault with firefox password importer. This vault use Advanced
* [AES encryption](https://fr.wikipedia.org/wiki/Advanced_Encryption_Standard) :key:
* Import your passwords from Firefox :earth_americas:
* Multilang support (:clipperton_island:, :us:)
+* Compatible Android et Windows
# The app in details
@@ -21,12 +22,18 @@ Personal password vault with firefox password importer. This vault use Advanced
![](https://github.com/DevElkami/PasswordVault/blob/master/vault-pwd.png)
-3. App preview
+3. App preview (WinForm)
![](https://github.com/DevElkami/PasswordVault/blob/master/vault-add.png)
![](https://github.com/DevElkami/PasswordVault/blob/master/vault-import.png)
![](https://github.com/DevElkami/PasswordVault/blob/master/vault-main.png)
+3. App preview (MAUI)
+
+![](https://github.com/DevElkami/PasswordVault/blob/master/android-1.en.jpg)
+![](https://github.com/DevElkami/PasswordVault/blob/master/android-2.en.jpg)
+![](https://github.com/DevElkami/PasswordVault/blob/master/android-3.en.jpg)
+
# Thanks :pray:
> [NLog](https://github.com/NLog)
diff --git a/VaultCore/MyVault.cs b/VaultCore/MyVault.cs
index d333cad..055cfab 100644
--- a/VaultCore/MyVault.cs
+++ b/VaultCore/MyVault.cs
@@ -115,13 +115,13 @@ public bool IsUnlock()
/// Initialize vault file
///
/// New vault key
- /// True if FILE_NAME already exist: we have a old file version
+ /// True if success
public bool Initialize(String key)
{
vaultKey = Security.GetHash(key);
File.WriteAllText(GetVaultPathKey(), Security.Encrypt(vaultKey, Security.GetHash(nameof(VaultCore) + nameof(Security))));
- return File.Exists(GetVaultPathData());
+ return File.Exists(GetVaultPathKey());
}
///
@@ -183,6 +183,21 @@ public void Load()
}
}
}
+
+ ///
+ /// Download file from internet
+ ///
+ public void Download(String url)
+ {
+ using (var client = new HttpClient())
+ {
+ var response = client.GetByteArrayAsync(url).Result;
+ File.WriteAllBytes(GetVaultPathData(), response);
+ client.CancelPendingRequests();
+ }
+
+ Load();
+ }
#endregion
}
diff --git a/VaultCore/VaultCore.csproj b/VaultCore/VaultCore.csproj
index 431ae3e..721cb6f 100644
--- a/VaultCore/VaultCore.csproj
+++ b/VaultCore/VaultCore.csproj
@@ -4,10 +4,10 @@
net7.0
enable
enable
- 3.2.0.0
- 3.2.0.0
+ 3.3.0.0
+ 3.3.0.0
DevElkami 2023
- 3.2.0.0
+ 3.3.0.0
diff --git a/WinformPasswordVault/Installer/Setup.iss b/WinformPasswordVault/Installer/Setup.iss
index 85bea4b..fab0163 100644
--- a/WinformPasswordVault/Installer/Setup.iss
+++ b/WinformPasswordVault/Installer/Setup.iss
@@ -1,5 +1,5 @@
#define MyAppName "Password vault"
-#define MyAppVersion "3.2.1.0"
+#define MyAppVersion "3.3.0.0"
#define MyAppPublisher "DevElkami"
#define MyAppURL "https://github.com/DevElkami/PasswordVault"
#define MyAppDescription "Password vault"
@@ -17,7 +17,7 @@ AppUpdatesURL={#MyAppURL}
DefaultDirName={autopf}\{#MyAppName}
DefaultGroupName={#MyAppName}
DisableProgramGroupPage=yes
-LicenseFile=..\..\LICENSE
+;LicenseFile=..\..\LICENSE
OutputBaseFilename=Password-Vault-{#MyAppVersion}
Compression=none
SolidCompression=yes
@@ -42,7 +42,7 @@ Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{
[Files]
Source: ..\bin\Release\net7.0-windows7.0\publish\WinformPasswordVault.exe; DestDir: {app}; Flags: ignoreversion overwritereadonly uninsremovereadonly;
Source: ..\bin\Release\net7.0-windows7.0\publish\*.dll; DestDir: {app}; Flags: ignoreversion overwritereadonly uninsremovereadonly;
-Source: ..\..\LICENSE; DestDir: {app}; Flags: overwritereadonly uninsremovereadonly; DestName: LICENSE.TXT
+;Source: ..\..\LICENSE; DestDir: {app}; Flags: overwritereadonly uninsremovereadonly; DestName: LICENSE.TXT
[Icons]
Name: {group}\Password Vault; Filename: {app}\WinformPasswordVault.exe; Flags: excludefromshowinnewinstall
diff --git a/android-1.en.jpg b/android-1.en.jpg
new file mode 100644
index 0000000..758d02d
Binary files /dev/null and b/android-1.en.jpg differ
diff --git a/android-1.fr.jpg b/android-1.fr.jpg
new file mode 100644
index 0000000..758d02d
Binary files /dev/null and b/android-1.fr.jpg differ
diff --git a/android-2.en.jpg b/android-2.en.jpg
new file mode 100644
index 0000000..9b44e4d
Binary files /dev/null and b/android-2.en.jpg differ
diff --git a/android-2.fr.jpg b/android-2.fr.jpg
new file mode 100644
index 0000000..9b44e4d
Binary files /dev/null and b/android-2.fr.jpg differ
diff --git a/android-3.en.jpg b/android-3.en.jpg
new file mode 100644
index 0000000..2d21f36
Binary files /dev/null and b/android-3.en.jpg differ
diff --git a/android-3.fr.jpg b/android-3.fr.jpg
new file mode 100644
index 0000000..2d21f36
Binary files /dev/null and b/android-3.fr.jpg differ