[BEEEP] [PM-3838] Refactor password callout (#6234)

This commit is contained in:
Oscar Hinton 2023-09-28 16:52:05 +02:00 committed by GitHub
parent 58cd35ef76
commit 80314f51a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 140 additions and 44 deletions

View File

@ -4,6 +4,7 @@ import remarkGfm from "remark-gfm";
const config: StorybookConfig = {
stories: [
"../libs/auth/src/**/*.stories.@(js|jsx|ts|tsx)",
"../libs/components/src/**/*.mdx",
"../libs/components/src/**/*.stories.@(js|jsx|ts|tsx)",
"../apps/web/src/**/*.mdx",

View File

@ -19,13 +19,12 @@
<app-callout type="warning"
>{{ "resetPasswordLoggedOutWarning" | i18n : loggedOutWarningName }}
</app-callout>
<app-callout
type="info"
[enforcedPolicyOptions]="enforcedPolicyOptions"
enforcedPolicyMessage="{{ 'resetPasswordMasterPasswordPolicyInEffect' | i18n }}"
<auth-password-callout
[policy]="enforcedPolicyOptions"
message="resetPasswordMasterPasswordPolicyInEffect"
*ngIf="enforcedPolicyOptions"
>
</app-callout>
</auth-password-callout>
<div class="row">
<div class="col form-group">
<div class="d-flex">

View File

@ -1,5 +1,7 @@
import { NgModule } from "@angular/core";
import { PasswordCalloutComponent } from "@bitwarden/auth";
import { LooseComponentsModule } from "../../../shared";
import { SharedOrganizationModule } from "../shared";
@ -19,6 +21,7 @@ import { PeopleComponent } from "./people.component";
LooseComponentsModule,
MembersRoutingModule,
UserDialogModule,
PasswordCalloutComponent,
],
declarations: [
BulkConfirmComponent,

View File

@ -25,12 +25,8 @@
</div>
<div class="tw-mb-3">
<app-callout
type="info"
[enforcedPolicyOptions]="enforcedPolicyOptions"
*ngIf="enforcedPolicyOptions"
>
</app-callout>
<auth-password-callout [policy]="enforcedPolicyOptions" *ngIf="enforcedPolicyOptions">
</auth-password-callout>
<bit-form-field>
<bit-label>{{ "masterPass" | i18n }}</bit-label>
<input

View File

@ -1,11 +1,13 @@
import { NgModule } from "@angular/core";
import { PasswordCalloutComponent } from "@bitwarden/auth";
import { SharedModule } from "../../shared";
import { RegisterFormComponent } from "./register-form.component";
@NgModule({
imports: [SharedModule],
imports: [SharedModule, PasswordCalloutComponent],
declarations: [RegisterFormComponent],
exports: [RegisterFormComponent],
})

View File

@ -17,12 +17,8 @@
{{ "resetPasswordAutoEnrollInviteWarning" | i18n }}
</app-callout>
<div class="form-group">
<app-callout
type="info"
[enforcedPolicyOptions]="enforcedPolicyOptions"
*ngIf="enforcedPolicyOptions"
>
</app-callout>
<auth-password-callout [policy]="enforcedPolicyOptions" *ngIf="enforcedPolicyOptions">
</auth-password-callout>
<label for="masterPassword">{{ "masterPass" | i18n }}</label>
<div class="d-flex">
<div class="w-100">

View File

@ -3,12 +3,8 @@
</div>
<bit-callout type="warning">{{ "loggedOutWarning" | i18n }}</bit-callout>
<app-callout
type="info"
[enforcedPolicyOptions]="enforcedPolicyOptions"
*ngIf="enforcedPolicyOptions"
>
</app-callout>
<auth-password-callout [policy]="enforcedPolicyOptions" *ngIf="enforcedPolicyOptions">
</auth-password-callout>
<form #form (ngSubmit)="submit()" [appApiAction]="formPromise" ngNativeValidate autocomplete="off">
<div class="row">

View File

@ -23,12 +23,8 @@
</div>
<div class="modal-body">
<app-callout type="warning">{{ "loggedOutWarning" | i18n }}</app-callout>
<app-callout
type="info"
[enforcedPolicyOptions]="enforcedPolicyOptions"
*ngIf="enforcedPolicyOptions"
>
</app-callout>
<auth-password-callout [policy]="enforcedPolicyOptions" *ngIf="enforcedPolicyOptions">
</auth-password-callout>
<div class="row">
<div class="col-6">
<div class="form-group">

View File

@ -5,11 +5,10 @@
<div class="card d-block">
<div class="card-body">
<app-callout type="warning">{{ "masterPasswordInvalidWarning" | i18n }} </app-callout>
<app-callout
type="info"
[enforcedPolicyOptions]="enforcedPolicyOptions"
<auth-password-callout
[policy]="enforcedPolicyOptions"
*ngIf="enforcedPolicyOptions"
></app-callout>
></auth-password-callout>
<form
#form

View File

@ -6,12 +6,8 @@
class="tw-block tw-rounded tw-border tw-border-solid tw-border-secondary-300 tw-bg-background tw-p-8"
>
<app-callout type="warning">{{ masterPasswordWarningText }} </app-callout>
<app-callout
type="info"
[enforcedPolicyOptions]="enforcedPolicyOptions"
*ngIf="enforcedPolicyOptions"
>
</app-callout>
<auth-password-callout [policy]="enforcedPolicyOptions" *ngIf="enforcedPolicyOptions">
</auth-password-callout>
<bit-form-field *ngIf="requireCurrentPassword">
<bit-label>{{ "currentMasterPass" | i18n }}</bit-label>
<input

View File

@ -1,5 +1,7 @@
import { NgModule } from "@angular/core";
import { PasswordCalloutComponent } from "@bitwarden/auth";
import { OrganizationSwitcherComponent } from "../admin-console/components/organization-switcher.component";
import { OrganizationCreateModule } from "../admin-console/organizations/create/organization-create.module";
import { OrganizationLayoutComponent } from "../admin-console/organizations/layouts/organization-layout.component";
@ -126,6 +128,7 @@ import { SharedModule } from "./shared.module";
// To be removed when OrganizationPlansComponent is moved to its own module (see AC-1453)
SecretsManagerBillingModule,
PasswordCalloutComponent,
],
declarations: [
AcceptEmergencyComponent,

View File

@ -76,8 +76,4 @@
}
}
}
.enforced-policy-options ul {
margin-bottom: 0px;
}
}

View File

@ -1 +1,2 @@
export * from "./components/fingerprint-dialog.component";
export * from "./password-callout/password-callout.component";

View File

@ -0,0 +1,24 @@
<bit-callout>
{{ message | i18n }}
<ul *ngIf="policy" class="tw-mb-0">
<li *ngIf="policy?.minComplexity > 0">
{{ "policyInEffectMinComplexity" | i18n : getPasswordScoreAlertDisplay() }}
</li>
<li *ngIf="policy?.minLength > 0">
{{ "policyInEffectMinLength" | i18n : policy?.minLength.toString() }}
</li>
<li *ngIf="policy?.requireUpper">
{{ "policyInEffectUppercase" | i18n }}
</li>
<li *ngIf="policy?.requireLower">
{{ "policyInEffectLowercase" | i18n }}
</li>
<li *ngIf="policy?.requireNumbers">
{{ "policyInEffectNumbers" | i18n }}
</li>
<li *ngIf="policy?.requireSpecial">
{{ "policyInEffectSpecial" | i18n : "!@#$%^&*" }}
</li>
</ul>
</bit-callout>

View File

@ -0,0 +1,36 @@
import { CommonModule } from "@angular/common";
import { Component, Input } from "@angular/core";
import { JslibModule } from "@bitwarden/angular/jslib.module";
import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { CalloutModule } from "@bitwarden/components";
@Component({
selector: "auth-password-callout",
templateUrl: "password-callout.component.html",
standalone: true,
imports: [CommonModule, JslibModule, CalloutModule],
})
export class PasswordCalloutComponent {
@Input() message = "masterPasswordPolicyInEffect";
@Input() policy: MasterPasswordPolicyOptions;
constructor(private i18nService: I18nService) {}
getPasswordScoreAlertDisplay() {
let str: string;
switch (this.policy.minComplexity) {
case 4:
str = this.i18nService.t("strong");
break;
case 3:
str = this.i18nService.t("good");
break;
default:
str = this.i18nService.t("weak");
break;
}
return str + " (" + this.policy.minComplexity + ")";
}
}

View File

@ -0,0 +1,52 @@
import { Meta, StoryObj, moduleMetadata } from "@storybook/angular";
import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { I18nMockService } from "@bitwarden/components";
import { PasswordCalloutComponent } from "./password-callout.component";
export default {
title: "Auth/Password Callout",
component: PasswordCalloutComponent,
decorators: [
moduleMetadata({
providers: [
{
provide: I18nService,
useFactory: () => {
return new I18nMockService({
masterPasswordPolicyInEffect:
"One or more organization policies require your master password to meet the following requirements:",
policyInEffectMinLength: "Minimum length of __$1__",
policyInEffectMinComplexity: "Minimum complexity score of __$1__",
policyInEffectUppercase: "Contain one or more uppercase characters",
policyInEffectLowercase: "Contain one or more lowercase characters",
policyInEffectNumbers: "Contain one or more numbers",
policyInEffectSpecial:
"Contain one or more of the following special characters $CHARS$",
weak: "Weak",
good: "Good",
strong: "Strong",
});
},
},
],
}),
],
} as Meta;
type Story = StoryObj<PasswordCalloutComponent>;
export const Default: Story = {
args: {
policy: {
minComplexity: 3,
minLength: 10,
requireUpper: true,
requireLower: true,
requireNumbers: true,
requireSpecial: true,
} as MasterPasswordPolicyOptions,
},
};