1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-15 07:43:35 +00:00

[SG-414] Refactor password strength component (#3186)

* moved password strength to libs

* refactored password strength component

* made changes on desktop and browser to reuse component

* resolved suggestions from PR review

* shared module restructure

* shared module restructure
This commit is contained in:
Gbubemi Smith
2022-08-01 23:26:50 +01:00
committed by GitHub
parent 8820a42ec9
commit 257fb0c0af
27 changed files with 259 additions and 425 deletions

View File

@@ -32,11 +32,15 @@
name="MasterPasswordHash"
class="text-monospace form-control mb-1"
[(ngModel)]="masterPassword"
(input)="updatePasswordStrength()"
required
appInputVerbatim
/>
<app-password-strength [score]="masterPasswordScore" [showText]="true">
<app-password-strength
[password]="masterPassword"
[email]="email"
[showText]="true"
(passwordStrengthResult)="getStrengthResult($event)"
>
</app-password-strength>
</div>
<div>

View File

@@ -44,13 +44,13 @@
name="NewMasterPasswordHash"
class="form-control mb-1"
[(ngModel)]="masterPassword"
(input)="updatePasswordStrength()"
required
appInputVerbatim
autocomplete="new-password"
/>
<app-password-strength
[score]="masterPasswordScore"
[password]="masterPassword"
[email]="email"
[showText]="true"
></app-password-strength>
</div>

View File

@@ -21,11 +21,14 @@
name="MasterPasswordHash"
class="text-monospace form-control mb-1"
[(ngModel)]="masterPassword"
(input)="updatePasswordStrength()"
required
appInputVerbatim
/>
<app-password-strength [score]="masterPasswordScore" [showText]="true">
<app-password-strength
[password]="masterPassword"
[email]="email"
[showText]="true"
>
</app-password-strength>
</div>
<div>

View File

@@ -1,14 +0,0 @@
<div class="progress">
<div
class="progress-bar {{ color }}"
role="progressbar"
[ngStyle]="{ width: scoreWidth + '%' }"
attr.aria-valuenow="{{ scoreWidth }}"
aria-valuemin="0"
aria-valuemax="100"
>
<ng-container *ngIf="showText && text">
{{ text }}
</ng-container>
</div>
</div>

View File

@@ -1,40 +0,0 @@
import { Component, Input, OnChanges } from "@angular/core";
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
@Component({
selector: "app-password-strength",
templateUrl: "password-strength.component.html",
})
export class PasswordStrengthComponent implements OnChanges {
@Input() score?: number;
@Input() showText = false;
scoreWidth = 0;
color = "bg-danger";
text: string;
constructor(private i18nService: I18nService) {}
ngOnChanges(): void {
this.scoreWidth = this.score == null ? 0 : (this.score + 1) * 20;
switch (this.score) {
case 4:
this.color = "bg-success";
this.text = this.i18nService.t("strong");
break;
case 3:
this.color = "bg-primary";
this.text = this.i18nService.t("good");
break;
case 2:
this.color = "bg-warning";
this.text = this.i18nService.t("weak");
break;
default:
this.color = "bg-danger";
this.text = this.score != null ? this.i18nService.t("weak") : null;
break;
}
}
}

View File

@@ -34,7 +34,6 @@
<input
id="register-form_input_master-password"
bitInput
(input)="updatePasswordStrength()"
type="{{ showPassword ? 'text' : 'password' }}"
formControlName="masterPassword"
/>
@@ -50,7 +49,13 @@
{{ "masterPassImportant" | i18n }}
</bit-hint>
</bit-form-field>
<app-password-strength [score]="masterPasswordScore" [showText]="true">
<app-password-strength
[password]="formGroup.get('masterPassword')?.value"
[email]="formGroup.get('email')?.value"
[name]="formGroup.get('name')?.value"
[showText]="true"
(passwordStrengthResult)="getStrengthResult($event)"
>
</app-password-strength>
</div>

View File

@@ -69,7 +69,7 @@ export class RegisterFormComponent extends BaseRegisterComponent {
if (
this.enforcedPolicyOptions != null &&
!this.policyService.evaluateMasterPassword(
this.masterPasswordScore,
this.passwordStrengthResult.score,
this.formGroup.get("masterPassword")?.value,
this.enforcedPolicyOptions
)

View File

@@ -66,7 +66,6 @@ import {
MenuModule,
} from "@bitwarden/components";
import { PasswordStrengthComponent } from "../components/password-strength.component";
import { PaymentComponent } from "../settings/payment.component";
import { TaxInfoComponent } from "../settings/tax-info.component";
@@ -122,7 +121,7 @@ registerLocaleData(localeZhCn, "zh-CN");
registerLocaleData(localeZhTw, "zh-TW");
@NgModule({
declarations: [PasswordStrengthComponent, PaymentComponent, TaxInfoComponent],
declarations: [PaymentComponent, TaxInfoComponent],
imports: [
CommonModule,
DragDropModule,
@@ -158,7 +157,6 @@ registerLocaleData(localeZhTw, "zh-TW");
MenuModule,
FormFieldModule,
SubmitButtonModule,
PasswordStrengthComponent,
PaymentComponent,
TaxInfoComponent,
],

View File

@@ -53,7 +53,6 @@
required
appInputVerbatim
autocomplete="new-password"
(input)="updatePasswordStrength()"
/>
<div class="input-group-append">
<button
@@ -78,7 +77,7 @@
</button>
</div>
</div>
<app-password-strength [score]="masterPasswordScore" [showText]="true">
<app-password-strength [password]="newPassword" [email]="email" [showText]="true">
</app-password-strength>
</div>
</div>

View File

@@ -1,5 +1,6 @@
import { Component, EventEmitter, Input, OnInit, Output } from "@angular/core";
import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from "@angular/core";
import { PasswordStrengthComponent } from "@bitwarden/angular/shared/components/password-strength/password-strength.component";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { CryptoService } from "@bitwarden/common/abstractions/crypto.service";
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
@@ -22,13 +23,13 @@ export class ResetPasswordComponent implements OnInit {
@Input() id: string;
@Input() organizationId: string;
@Output() onPasswordReset = new EventEmitter();
@ViewChild(PasswordStrengthComponent) passwordStrengthComponent: PasswordStrengthComponent;
enforcedPolicyOptions: MasterPasswordPolicyOptions;
newPassword: string = null;
showPassword = false;
masterPasswordScore: number;
formPromise: Promise<any>;
private newPasswordStrengthTimeout: any;
constructor(
private apiService: ApiService,
@@ -52,7 +53,7 @@ export class ResetPasswordComponent implements OnInit {
async generatePassword() {
const options = (await this.passwordGenerationService.getOptions())[0];
this.newPassword = await this.passwordGenerationService.generatePassword(options);
this.updatePasswordStrength();
this.passwordStrengthComponent.updatePasswordStrength(this.newPassword);
}
togglePassword() {
@@ -183,35 +184,4 @@ export class ResetPasswordComponent implements OnInit {
this.logService.error(e);
}
}
updatePasswordStrength() {
if (this.newPasswordStrengthTimeout != null) {
clearTimeout(this.newPasswordStrengthTimeout);
}
this.newPasswordStrengthTimeout = setTimeout(() => {
const strengthResult = this.passwordGenerationService.passwordStrength(
this.newPassword,
this.getPasswordStrengthUserInput()
);
this.masterPasswordScore = strengthResult == null ? null : strengthResult.score;
}, 300);
}
private getPasswordStrengthUserInput() {
let userInput: string[] = [];
const atPosition = this.email.indexOf("@");
if (atPosition > -1) {
userInput = userInput.concat(
this.email
.substr(0, atPosition)
.trim()
.toLowerCase()
.split(/[^A-Za-z0-9]/)
);
}
if (this.name != null && this.name !== "") {
userInput = userInput.concat(this.name.trim().toLowerCase().split(" "));
}
return userInput;
}
}

View File

@@ -37,15 +37,17 @@
name="NewMasterPasswordHash"
class="form-control mb-1"
[(ngModel)]="masterPassword"
(input)="updatePasswordStrength()"
required
appInputVerbatim
autocomplete="new-password"
/>
<app-password-strength
[score]="masterPasswordScore"
[password]="masterPassword"
[email]="email"
[showText]="true"
></app-password-strength>
(passwordStrengthResult)="getStrengthResult($event)"
>
</app-password-strength>
</div>
</div>
<div class="col-6">

View File

@@ -39,12 +39,16 @@
name="NewMasterPasswordHash"
class="form-control mb-1"
[(ngModel)]="masterPassword"
(input)="updatePasswordStrength()"
required
appInputVerbatim
autocomplete="new-password"
/>
<app-password-strength [score]="masterPasswordScore" [showText]="true">
<app-password-strength
[password]="masterPassword"
[email]="email"
[showText]="true"
(passwordStrengthResult)="getStrengthResult($event)"
>
</app-password-strength>
</div>
</div>