Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
DefinePasswordViewModel.cs
1using System.ComponentModel;
2using CommunityToolkit.Mvvm.ComponentModel;
3using CommunityToolkit.Mvvm.Input;
4using Microsoft.Maui.Controls.Shapes;
9
11{
12 public partial class DefinePasswordViewModel : BaseRegistrationViewModel
13 {
15 : base(RegistrationStep.DefinePassword)
16 {
17 }
18
20 protected override async Task OnInitialize()
21 {
22 await base.OnInitialize();
23
24 LocalizationManager.Current.PropertyChanged += this.LocalizationManagerEventHandler;
25 }
26
28 protected override async Task OnDispose()
29 {
30 LocalizationManager.Current.PropertyChanged -= this.LocalizationManagerEventHandler;
31
32 await base.OnDispose();
33 }
34
38 public void LocalizationManagerEventHandler(object? sender, PropertyChangedEventArgs e)
39 {
40 this.OnPropertyChanged(nameof(this.LocalizedValidationError));
41 this.UpdateToggleKeyboardText();
42 this.UpdateSecurityScore();
43 }
44
45 [ObservableProperty]
46 [NotifyPropertyChangedFor(nameof(PasswordsMatch))]
47 [NotifyCanExecuteChangedFor(nameof(ContinueCommand))]
48 private string? passwordText1;
49
50 [ObservableProperty]
51 [NotifyPropertyChangedFor(nameof(IsPassword2NotValid))]
52 [NotifyPropertyChangedFor(nameof(PasswordsMatch))]
53 [NotifyCanExecuteChangedFor(nameof(ContinueCommand))]
54 private string? passwordText2;
55
56
57 [ObservableProperty]
58 [NotifyPropertyChangedFor(nameof(PasswordVisibilityPathData))]
59
60 private bool isPasswordHidden = true;
61
62
63 [ObservableProperty]
64 private double securityBar1Percentage;
65
66 [ObservableProperty]
67 private double securityBar2Percentage;
68
69 [ObservableProperty]
70 private double securityBar3Percentage;
71
72 [ObservableProperty]
73 private Color securityTextColor = AppColors.WeakPasswordForeground;
74
75 [ObservableProperty]
76 private string securityText = ServiceRef.Localizer[nameof(AppResources.PasswordWeakSecurity)];
77
78 [ObservableProperty]
79 private string toggleNumericPasswordText = ServiceRef.Localizer[nameof(AppResources.OnboardingDefinePasswordCreateNumeric)];
80
81 [ObservableProperty]
82 private Keyboard keyboardType = Keyboard.Numeric;
83
84 [ObservableProperty]
85 private string toggleKeyboardTypeText = ServiceRef.Localizer[nameof(AppResources.OnboardingDefinePasswordCreateAlphanumeric)];
86
87
88
89
90 partial void OnPasswordText1Changed(string? value)
91 {
92 this.UpdateSecurityScore();
93 }
94
95 private void UpdateSecurityScore()
96 {
97 double Score = ServiceRef.TagProfile.CalculatePasswordScore(this.PasswordText1);
98
102
103 this.SecurityBar1Percentage = (Math.Min(Score, low) / low) * 100.0;
104 this.SecurityBar2Percentage = Math.Max((Math.Min(Score - low, medium - low) / (medium - low) * 100.0), 0);
105 this.SecurityBar3Percentage = Math.Max((Math.Min(Score - medium, high - medium) / (high - medium) * 100.0), 0);
106
107 if (Score >= medium)
108 {
109 this.SecurityTextColor = AppColors.StrongPasswordForeground;
110 this.SecurityText = ServiceRef.Localizer[nameof(AppResources.PasswordStrongSecurity)];
111 }
112 else if (Score >= low)
113 {
114 this.SecurityTextColor = AppColors.MediumPasswordForeground;
115 this.SecurityText = ServiceRef.Localizer[nameof(AppResources.PasswordMediumSecurity)];
116 }
117 else
118 {
119 this.SecurityTextColor = AppColors.WeakPasswordForeground;
120 this.SecurityText = ServiceRef.Localizer[nameof(AppResources.PasswordWeakSecurity)];
121 }
122 }
123
124 [RelayCommand]
125 private void TogglePasswordVisibility()
126 {
127 this.IsPasswordHidden = !this.IsPasswordHidden;
128 }
129
130 [RelayCommand]
131 private void ValidatePassword()
132 {
133 this.OnPropertyChanged(nameof(this.PasswordStrength));
134 this.OnPropertyChanged(nameof(this.LocalizedValidationError));
135 this.OnPropertyChanged(nameof(this.IsPassword1NotValid));
136 }
137
141 public Geometry PasswordVisibilityPathData => this.IsPasswordHidden ? Geometries.VisibilityOnPath : Geometries.VisibilityOffPath;
142
147
151 public bool PasswordsMatch
152 {
153 get
154 {
155 if (string.IsNullOrEmpty(this.PasswordText1))
156 return string.IsNullOrEmpty(this.PasswordText2);
157 else
158 return string.Equals(this.PasswordText1, this.PasswordText2, StringComparison.Ordinal);
159 }
160 }
161
165 public bool IsPassword1NotValid => !string.IsNullOrEmpty(this.PasswordText1) && this.PasswordStrength != PasswordStrength.Strong;
166
170 public bool IsPassword2NotValid => !string.IsNullOrEmpty(this.PasswordText2) && !this.PasswordsMatch;
171
175 public string LocalizedValidationError => GetLocalizedValidationError(this.PasswordStrength);
176
183 {
184 return PasswordStrength switch
185 {
186 PasswordStrength.NotEnoughDigitsLettersSigns => ServiceRef.Localizer[nameof(AppResources.PasswordWithNotEnoughDigitsLettersSigns), Constants.Security.MinPasswordSymbolsFromDifferentClasses],
187
188 PasswordStrength.NotEnoughDigitsOrSigns => ServiceRef.Localizer[nameof(AppResources.PasswordWithNotEnoughDigitsOrSigns), Constants.Security.MinPasswordSymbolsFromDifferentClasses],
189 PasswordStrength.NotEnoughLettersOrDigits => ServiceRef.Localizer[nameof(AppResources.PasswordWithNotEnoughLettersOrDigits), Constants.Security.MinPasswordSymbolsFromDifferentClasses],
190 PasswordStrength.NotEnoughLettersOrSigns => ServiceRef.Localizer[nameof(AppResources.PasswordWithNotEnoughLettersOrSigns), Constants.Security.MinPasswordSymbolsFromDifferentClasses],
191 PasswordStrength.TooManyIdenticalSymbols => ServiceRef.Localizer[nameof(AppResources.PasswordWithTooManyIdenticalSymbols), Constants.Security.MaxPasswordIdenticalSymbols],
192 PasswordStrength.TooManySequencedSymbols => ServiceRef.Localizer[nameof(AppResources.PasswordWithTooManySequencedSymbols), Constants.Security.MaxPasswordSequencedSymbols],
193 PasswordStrength.TooShort => ServiceRef.Localizer[nameof(AppResources.PasswordTooShort), Constants.Security.MinPasswordLength],
194
195 PasswordStrength.ContainsAddress => ServiceRef.Localizer[nameof(AppResources.PasswordContainsAddress)],
196 PasswordStrength.ContainsName => ServiceRef.Localizer[nameof(AppResources.PasswordContainsName)],
197 PasswordStrength.ContainsPersonalNumber => ServiceRef.Localizer[nameof(AppResources.PasswordContainsPersonalNumber)],
198 PasswordStrength.ContainsPhoneNumber => ServiceRef.Localizer[nameof(AppResources.PasswordContainsPhoneNumber)],
199 PasswordStrength.ContainsEMail => ServiceRef.Localizer[nameof(AppResources.PasswordContainsEMail)],
200 PasswordStrength.Strong => string.Empty,
201 _ => throw new NotImplementedException()
202 };
203 }
204
205 public bool CanContinue => this.PasswordStrength == PasswordStrength.Strong && this.PasswordsMatch;
206
207
208
209
210 [RelayCommand]
211 private void ToggleNumericPassword()
212 {
213 this.PasswordText1 = string.Empty;
214 this.PasswordText2 = string.Empty;
215
216 this.KeyboardType = this.KeyboardType == Keyboard.Numeric ? Keyboard.Default : Keyboard.Numeric;
217
218 this.UpdateToggleKeyboardText();
219 }
220
221 private void UpdateToggleKeyboardText()
222 {
223 if (this.KeyboardType == Keyboard.Default)
224 this.ToggleKeyboardTypeText = ServiceRef.Localizer[nameof(AppResources.OnboardingDefinePasswordCreateNumeric)];
225 else
226 this.ToggleKeyboardTypeText = ServiceRef.Localizer[nameof(AppResources.OnboardingDefinePasswordCreateAlphanumeric)];
227 }
228
229
230 [RelayCommand(CanExecute = nameof(CanContinue))]
231 private void Continue()
232 {
233 ServiceRef.PlatformSpecific.HideKeyboard();
234
235 bool isFirstPassword = string.IsNullOrEmpty(ServiceRef.TagProfile.LocalPasswordHash); //Wheter or not to go to the Finalize view
236
237 ServiceRef.TagProfile.LocalPassword = this.PasswordText1!;
238 if(ServiceRef.PlatformSpecific.SupportsFingerprintAuthentication && isFirstPassword)
239 GoToRegistrationStep(RegistrationStep.Biometrics);
240 else
241 GoToRegistrationStep(RegistrationStep.Complete);
242
243 if (ServiceRef.TagProfile.TestOtpTimestamp is not null)
244 {
245 ServiceRef.UiService.DisplayAlert(
246 ServiceRef.Localizer[nameof(AppResources.WarningTitle)],
247 ServiceRef.Localizer[nameof(AppResources.TestOtpUsed)],
248 ServiceRef.Localizer[nameof(AppResources.Ok)]);
249 }
250 }
251 }
252}
Authentication constants
Definition: Constants.cs:33
const int MaxPasswordIdenticalSymbols
Maximum number of identical symbols in a password.
Definition: Constants.cs:62
const int MinPasswordLength
Minimum length for password
Definition: Constants.cs:37
const int MinPasswordSymbolsFromDifferentClasses
Minimum number of symbols from at least two character classes (digits, letters, other) in a password.
Definition: Constants.cs:57
const int MaxPasswordSequencedSymbols
Maximum number of sequenced symbols in a password.
Definition: Constants.cs:67
const double MediumSecurityScoreThreshold
A password score value equal to or higher than this is considered medium security.
Definition: Constants.cs:42
const double HighSecurityPasswordScoreThreshold
A password score value equal to or higher than this is considered high security.
Definition: Constants.cs:47
const double MaxSecurityPasswordScoreThreshold
A password score value equal to or higher than this is considered to be of the highest security.
Definition: Constants.cs:52
A set of never changing property constants and helpful values.
Definition: Constants.cs:7
Base class that references services in the app.
Definition: ServiceRef.cs:31
static IUiService UiService
Service serializing and managing UI-related tasks.
Definition: ServiceRef.cs:55
static ITagProfile TagProfile
TAG Profile service.
Definition: ServiceRef.cs:79
static IStringLocalizer Localizer
Localization service
Definition: ServiceRef.cs:235
Static class that gives access to app-specific themed colors
Definition: AppColors.cs:7
static Color StrongPasswordForeground
Strong password foreground color.
Definition: AppColors.cs:542
static Color MediumPasswordForeground
Medium password foreground color.
Definition: AppColors.cs:522
static Color WeakPasswordForeground
Weak password foreground color.
Definition: AppColors.cs:502
Static class containing SVG Paths for symbols used in the app.
Definition: Geometries.cs:11
Geometry PasswordVisibilityPathData
Gets the path data for the password visibility icon depending if the password is hidden or not.
void LocalizationManagerEventHandler(object? sender, PropertyChangedEventArgs e)
EventHandler for localization change
static string GetLocalizedValidationError(PasswordStrength PasswordStrength)
Gets a localized error message, given a Password strength.
bool PasswordsMatch
Gets the value indicating whether the entered PasswordText1 is the same as the entered PasswordText2.
PasswordStrength ValidatePasswordStrength(string? Password)
Validates if the Password is strong enough.
DateTime? TestOtpTimestamp
Returns a timestamp if the user used a Test OTP Code.
Definition: ITagProfile.cs:206
string? LocalPasswordHash
A hashed version of the user's LocalPassword.
Definition: ITagProfile.cs:176
double CalculatePasswordScore(string? Password)
Returns a score for the password, which is based on the number of bits of security the password provi...
PasswordStrength
Represents a result of validating password strength.
RegistrationStep
The different steps of a TAG Profile registration journey.