mirror of
https://github.com/aliasvault/aliasvault.git
synced 2026-03-27 02:52:04 -04:00
Use shared ValidationMessages.en.resx (#773)
This commit is contained in:
@@ -62,6 +62,7 @@
|
||||
|
||||
@code {
|
||||
private IStringLocalizer Localizer => LocalizerFactory.Create("Components.Auth.Setup.PasswordStep", "AliasVault.Client");
|
||||
private IStringLocalizer ValidationLocalizer => LocalizerFactory.Create("ValidationMessages", "AliasVault.Client");
|
||||
|
||||
/// <summary>
|
||||
/// The event callback for when the password changes.
|
||||
@@ -173,7 +174,7 @@
|
||||
{
|
||||
if (Password.Length < PasswordStrengthConstants.MinimumGoodPasswordLength)
|
||||
{
|
||||
_errorMessage = Localizer["PasswordTooShortError", PasswordStrengthConstants.MinimumGoodPasswordLength];
|
||||
_errorMessage = ValidationLocalizer["PasswordMinLengthGeneric", PasswordStrengthConstants.MinimumGoodPasswordLength];
|
||||
await OnPasswordChange.InvokeAsync(string.Empty);
|
||||
StateHasChanged();
|
||||
return;
|
||||
@@ -189,7 +190,7 @@
|
||||
|
||||
if (Password != ConfirmPassword)
|
||||
{
|
||||
_errorMessage = Localizer["PasswordsMismatchError"];
|
||||
_errorMessage = ValidationLocalizer["PasswordsDoNotMatchGeneric"];
|
||||
await OnPasswordChange.InvokeAsync(string.Empty);
|
||||
StateHasChanged();
|
||||
return;
|
||||
|
||||
@@ -3,7 +3,10 @@
|
||||
@using AliasVault.Client.Main.Components.Shared
|
||||
@using AliasVault.Client.Main.Components.Layout
|
||||
@using AliasVault.Client.Auth.Components
|
||||
@using AliasVault.Client.Main.Constants
|
||||
@using System.Timers
|
||||
@inject IStringLocalizerFactory LocalizerFactory
|
||||
@implements IDisposable
|
||||
|
||||
<FormModal
|
||||
IsOpen="@IsOpen"
|
||||
@@ -36,6 +39,7 @@
|
||||
@bind-Value="_exportPassword"
|
||||
Placeholder=""
|
||||
@onkeydown="HandleKeyDown"
|
||||
@onfocus="OnPasswordFocus"
|
||||
autofocus="true" />
|
||||
|
||||
<PasswordStrengthIndicator Password="@_exportPassword" OnStrengthChanged="@HandleStrengthChanged" />
|
||||
@@ -49,13 +53,16 @@
|
||||
Id="confirmExportPassword"
|
||||
@bind-Value="_confirmPassword"
|
||||
Placeholder=""
|
||||
@onkeydown="HandleKeyDown" />
|
||||
|
||||
@if (!string.IsNullOrEmpty(_confirmPassword) && _exportPassword != _confirmPassword)
|
||||
{
|
||||
<p class="mt-1 text-xs text-red-600 dark:text-red-400">@Localizer["PasswordsDoNotMatch"]</p>
|
||||
}
|
||||
@onkeydown="HandleKeyDown"
|
||||
@onfocus="OnPasswordFocus" />
|
||||
</div>
|
||||
|
||||
@if (!string.IsNullOrEmpty(_validationError))
|
||||
{
|
||||
<div class="mt-2 text-sm text-red-600 dark:text-red-400">
|
||||
@_validationError
|
||||
</div>
|
||||
}
|
||||
</ChildContent>
|
||||
<FooterContent>
|
||||
<button
|
||||
@@ -93,20 +100,57 @@
|
||||
[Parameter]
|
||||
public EventCallback OnClose { get; set; }
|
||||
|
||||
private string _exportPassword = string.Empty;
|
||||
private string _confirmPassword = string.Empty;
|
||||
private string _exportPasswordValue = string.Empty;
|
||||
private string _confirmPasswordValue = string.Empty;
|
||||
private int _passwordStrength = 0;
|
||||
private string _validationError = string.Empty;
|
||||
private Timer? _passwordDebounceTimer;
|
||||
|
||||
private string _exportPassword
|
||||
{
|
||||
get => _exportPasswordValue;
|
||||
set
|
||||
{
|
||||
if (_exportPasswordValue != value)
|
||||
{
|
||||
_exportPasswordValue = value;
|
||||
ValidatePasswordWithDebounce();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string _confirmPassword
|
||||
{
|
||||
get => _confirmPasswordValue;
|
||||
set
|
||||
{
|
||||
if (_confirmPasswordValue != value)
|
||||
{
|
||||
_confirmPasswordValue = value;
|
||||
ValidatePasswordImmediate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IStringLocalizer Localizer => LocalizerFactory.Create("Pages.Main.Settings.ImportExport.Components.ExportPasswordModal", "AliasVault.Client");
|
||||
private IStringLocalizer SharedLocalizer => LocalizerFactory.Create("Shared", "AliasVault.Client");
|
||||
private IStringLocalizer ValidationLocalizer => LocalizerFactory.Create("ValidationMessages", "AliasVault.Client");
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
_passwordDebounceTimer = new Timer(800);
|
||||
_passwordDebounceTimer.Elapsed += async (sender, e) => await ValidatePasswordDebounced();
|
||||
_passwordDebounceTimer.AutoReset = false;
|
||||
}
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
if (!IsOpen)
|
||||
{
|
||||
_exportPassword = string.Empty;
|
||||
_confirmPassword = string.Empty;
|
||||
_exportPasswordValue = string.Empty;
|
||||
_confirmPasswordValue = string.Empty;
|
||||
_passwordStrength = 0;
|
||||
_validationError = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,21 +159,75 @@
|
||||
_passwordStrength = strength;
|
||||
}
|
||||
|
||||
private void OnPasswordFocus(FocusEventArgs e)
|
||||
{
|
||||
_validationError = string.Empty;
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private void ValidatePasswordWithDebounce()
|
||||
{
|
||||
_validationError = string.Empty;
|
||||
StateHasChanged();
|
||||
|
||||
_passwordDebounceTimer?.Stop();
|
||||
_passwordDebounceTimer?.Start();
|
||||
}
|
||||
|
||||
private async void ValidatePasswordImmediate()
|
||||
{
|
||||
await ValidatePasswordDebounced();
|
||||
}
|
||||
|
||||
private async Task ValidatePasswordDebounced()
|
||||
{
|
||||
await InvokeAsync(() =>
|
||||
{
|
||||
var minLength = PasswordStrengthConstants.MinimumGoodPasswordLength;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(_exportPasswordValue) &&
|
||||
_exportPasswordValue.Length < minLength)
|
||||
{
|
||||
_validationError = ValidationLocalizer["PasswordMinLengthGeneric", minLength];
|
||||
StateHasChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(_confirmPasswordValue) &&
|
||||
_exportPasswordValue != _confirmPasswordValue)
|
||||
{
|
||||
_validationError = ValidationLocalizer["PasswordsDoNotMatchGeneric"];
|
||||
StateHasChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
_validationError = string.Empty;
|
||||
StateHasChanged();
|
||||
});
|
||||
}
|
||||
|
||||
private bool IsPasswordValid()
|
||||
{
|
||||
return !string.IsNullOrEmpty(_exportPassword) &&
|
||||
!string.IsNullOrEmpty(_confirmPassword) &&
|
||||
_exportPassword == _confirmPassword &&
|
||||
_exportPassword.Length >= 8;
|
||||
return !string.IsNullOrEmpty(_exportPasswordValue) &&
|
||||
!string.IsNullOrEmpty(_confirmPasswordValue) &&
|
||||
_exportPasswordValue == _confirmPasswordValue &&
|
||||
string.IsNullOrEmpty(_validationError) &&
|
||||
_exportPasswordValue.Length >= PasswordStrengthConstants.MinimumGoodPasswordLength;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_passwordDebounceTimer?.Dispose();
|
||||
}
|
||||
|
||||
private async Task HandleSubmit()
|
||||
{
|
||||
if (IsPasswordValid())
|
||||
{
|
||||
await OnPasswordSubmitted.InvokeAsync(_exportPassword);
|
||||
_exportPassword = string.Empty;
|
||||
_confirmPassword = string.Empty;
|
||||
await OnPasswordSubmitted.InvokeAsync(_exportPasswordValue);
|
||||
_exportPasswordValue = string.Empty;
|
||||
_confirmPasswordValue = string.Empty;
|
||||
_validationError = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -85,6 +85,7 @@ else
|
||||
|
||||
private IStringLocalizer Localizer => LocalizerFactory.Create("Components.Main.Pages.Settings.Security.ChangePassword", "AliasVault.Client");
|
||||
private IStringLocalizer ApiErrorLocalizer => LocalizerFactory.Create("ApiErrors", "AliasVault.Client");
|
||||
private IStringLocalizer ValidationLocalizer => LocalizerFactory.Create("ValidationMessages", "AliasVault.Client");
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current user's password salt.
|
||||
@@ -201,7 +202,7 @@ else
|
||||
if (!string.IsNullOrWhiteSpace(PasswordChangeFormModel.NewPassword) &&
|
||||
PasswordChangeFormModel.NewPassword.Length < minLength)
|
||||
{
|
||||
PasswordValidationError = Localizer["PasswordStrengthTooWeakError", minLength];
|
||||
PasswordValidationError = ValidationLocalizer["PasswordMinLengthGeneric", minLength];
|
||||
StateHasChanged();
|
||||
return;
|
||||
}
|
||||
@@ -209,7 +210,7 @@ else
|
||||
if (!string.IsNullOrWhiteSpace(PasswordChangeFormModel.NewPasswordConfirm) &&
|
||||
PasswordChangeFormModel.NewPassword != PasswordChangeFormModel.NewPasswordConfirm)
|
||||
{
|
||||
PasswordValidationError = Localizer["PasswordsMismatchError"];
|
||||
PasswordValidationError = ValidationLocalizer["PasswordsDoNotMatchGeneric"];
|
||||
StateHasChanged();
|
||||
return;
|
||||
}
|
||||
@@ -295,7 +296,7 @@ else
|
||||
var minLength = PasswordStrengthConstants.MinimumGoodPasswordLength;
|
||||
if (PasswordChangeFormModel.NewPassword.Length < minLength)
|
||||
{
|
||||
PasswordValidationError = Localizer["PasswordStrengthTooWeakError", minLength];
|
||||
PasswordValidationError = ValidationLocalizer["PasswordMinLengthGeneric", minLength];
|
||||
StateHasChanged();
|
||||
return;
|
||||
}
|
||||
@@ -303,7 +304,7 @@ else
|
||||
// Validate password strength before proceeding
|
||||
if (PasswordStrengthIndicatorRef == null || !PasswordStrengthIndicatorRef.MeetsMinimumRequirement())
|
||||
{
|
||||
PasswordValidationError = Localizer["PasswordStrengthTooWeakError", PasswordStrengthConstants.MinimumGoodPasswordLength];
|
||||
PasswordValidationError = ValidationLocalizer["PasswordMinLengthGeneric", PasswordStrengthConstants.MinimumGoodPasswordLength];
|
||||
StateHasChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -64,16 +64,8 @@
|
||||
<value>Password is valid and strong!</value>
|
||||
<comment>Success message for valid password</comment>
|
||||
</data>
|
||||
<data name="PasswordTooShortError">
|
||||
<value>Master password must be at least {0} characters long.</value>
|
||||
<comment>Error message for password too short. {0} is the minimum password length.</comment>
|
||||
</data>
|
||||
<data name="ConfirmPasswordPrompt">
|
||||
<value>Confirm your password by entering it again.</value>
|
||||
<comment>Prompt to confirm password</comment>
|
||||
</data>
|
||||
<data name="PasswordsMismatchError">
|
||||
<value>Passwords do not match.</value>
|
||||
<comment>Error message when passwords don't match</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -116,12 +116,4 @@
|
||||
<value>Failed to change password. Please refresh the page and try again.</value>
|
||||
<comment>Error message when password change fails</comment>
|
||||
</data>
|
||||
<data name="PasswordStrengthTooWeakError" xml:space="preserve">
|
||||
<value>Your new password must be at least {0} characters long.</value>
|
||||
<comment>Error message when password strength is too weak. {0} is the minimum password length.</comment>
|
||||
</data>
|
||||
<data name="PasswordsMismatchError" xml:space="preserve">
|
||||
<value>Passwords do not match.</value>
|
||||
<comment>Error message when new password and confirmation password don't match</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -66,10 +66,6 @@
|
||||
<value>Confirm Password</value>
|
||||
<comment>Label for password confirmation field</comment>
|
||||
</data>
|
||||
<data name="PasswordsDoNotMatch" xml:space="preserve">
|
||||
<value>Passwords do not match</value>
|
||||
<comment>Error when passwords don't match</comment>
|
||||
</data>
|
||||
<data name="CreateEncryptedExportButton" xml:space="preserve">
|
||||
<value>Create Encrypted Export</value>
|
||||
<comment>Button text for creating encrypted export</comment>
|
||||
|
||||
Reference in New Issue
Block a user