From 9ec01422dfe7136e177aee2d224c41dc734e3384 Mon Sep 17 00:00:00 2001 From: rr-bw <102181210+rr-bw@users.noreply.github.com> Date: Tue, 25 Jun 2024 09:04:49 -0700 Subject: [PATCH] [PM-5085] Add additional InputPasswordComponent story and docs (#9752) * split stories: 1 default, 1 with policy * add storybook docs --- .../angular/input-password/input-password.mdx | 75 +++++++++++++++++++ .../input-password/input-password.stories.ts | 30 ++++++-- 2 files changed, 100 insertions(+), 5 deletions(-) create mode 100644 libs/auth/src/angular/input-password/input-password.mdx diff --git a/libs/auth/src/angular/input-password/input-password.mdx b/libs/auth/src/angular/input-password/input-password.mdx new file mode 100644 index 0000000000..d442ea02fc --- /dev/null +++ b/libs/auth/src/angular/input-password/input-password.mdx @@ -0,0 +1,75 @@ +import { Meta, Story } from "@storybook/addon-docs"; + +import * as stories from "./input-password.stories.ts"; + + + +# InputPassword Component + +The `InputPasswordComponent` allows a user to enter a master password and hint. On submission it +creates a master key, master key hash, and emits those values to the parent (along with the hint and +default kdfConfig). + +The component is intended for re-use in different scenarios throughout the application. Therefore it +is mostly presentational and simply emits values rather than acting on them itself. It is the job of +the parent component to act on those values as needed. + +
+ +## `@Input()`'s + +- `email` (**required**) - the parent component must provide an email so that the + `InputPasswordComponent` can create a master key. +- `buttonText` (optional) - an `i18n` translated string that can be used as button text (default + text is "Set master password"). +- `orgId` (optional) - used to retreive and enforce the master password policy requirements for an + org. + +
+ +## Form Input Fields + +The `InputPasswordComponent` allows a user to enter: + +1. Master password +2. Master password confirmation +3. Hint (optional) +4. Chooses whether to check for password breaches (checkbox) + +Validation ensures that the master password and confirmed master password are the same, and that the +master password and hint values are not the same. + +
+ +## On Submit + +When the form is submitted, the `InputPasswordComponent` does the following in order: + +1. If the user selected the checkbox to check for password breaches, they will recieve a popup + dialog if their entered password is found in a breach. The popup will give them the option to + continue with the password or to back out and choose a different password. +2. If there is a master password policy being enforced by an org, it will check to make sure the + entered master password meets the policy requirements. +3. The component will use the password, email, and default kdfConfig to create a master key and + master key hash. +4. The component will emit the following values (defined in the `PasswordInputResult` interface) to + be used by the parent component as needed: + +```typescript +export interface PasswordInputResult { + masterKey: MasterKey; + masterKeyHash: string; + kdfConfig: PBKDF2KdfConfig; + hint: string; +} +``` + +# Default Example + + + +
+ +# With Policy Requrements + + diff --git a/libs/auth/src/angular/input-password/input-password.stories.ts b/libs/auth/src/angular/input-password/input-password.stories.ts index 6144e39e64..a0dee87b27 100644 --- a/libs/auth/src/angular/input-password/input-password.stories.ts +++ b/libs/auth/src/angular/input-password/input-password.stories.ts @@ -29,7 +29,10 @@ const mockMasterPasswordPolicyOptions = { export default { title: "Auth/Input Password", component: InputPasswordComponent, - decorators: [ +} as Meta; + +const decorators = (options: { hasPolicy?: boolean }) => { + return [ applicationConfig({ providers: [ importProvidersFrom(PreloadedEnglishI18nModule), @@ -56,13 +59,15 @@ export default { { provide: PolicyApiServiceAbstraction, useValue: { - getMasterPasswordPolicyOptsForOrgUser: () => mockMasterPasswordPolicyOptions, + getMasterPasswordPolicyOptsForOrgUser: () => + options.hasPolicy ? mockMasterPasswordPolicyOptions : null, } as Partial, }, { provide: PolicyService, useValue: { - masterPasswordPolicyOptions$: () => of(mockMasterPasswordPolicyOptions), + masterPasswordPolicyOptions$: () => + options.hasPolicy ? of(mockMasterPasswordPolicyOptions) : null, evaluateMasterPassword: (score) => { if (score < 4) { return false; @@ -101,8 +106,8 @@ export default { }, ], }), - ], -} as Meta; + ]; +}; type Story = StoryObj; @@ -113,4 +118,19 @@ export const Default: Story = { `, }), + decorators: decorators({ + hasPolicy: false, + }), +}; + +export const WithPolicy: Story = { + render: (args) => ({ + props: args, + template: ` + + `, + }), + decorators: decorators({ + hasPolicy: true, + }), };