Skip to content

Commit 2d30ad6

Browse files
committed
[PM-18721] update storybook docs
1 parent db1f9bf commit 2d30ad6

File tree

1 file changed

+162
-64
lines changed

1 file changed

+162
-64
lines changed

libs/auth/src/angular/input-password/input-password.mdx

Lines changed: 162 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,21 @@ import * as stories from "./input-password.stories.ts";
66

77
# InputPassword Component
88

9-
The `InputPasswordComponent` allows a user to enter master password related credentials. On form
10-
submission, the component creates cryptographic properties (`newMasterKey`,
11-
`newServerMasterKeyHash`, etc.) and emits those properties to the parent (along with the other
12-
values defined in `PasswordInputResult`).
9+
The `InputPasswordComponent` allows a user to enter master password related credentials.
10+
Specifically, it does the following:
1311

14-
The component is intended for re-use in different scenarios throughout the application. Therefore it
15-
is mostly presentational and simply emits values rather than acting on them itself. It is the job of
16-
the parent component to act on those values as needed.
12+
1. Displays form fields in the UI
13+
2. Validates form fields
14+
3. Generates cryptographic properties based on the form inputs (e.g. `newMasterKey`,
15+
`newServerMasterKeyHash`, etc.)
16+
4. Emits the generated properties to the parent component
17+
18+
The `InputPasswordComponent` is central to our set/change password flows. It allows us to keep our
19+
form UI and validation logic consistent across our many set/change password flows.
20+
21+
The component is intended for re-use in different set/change password scenarios throughout the
22+
application. Therefore it is mostly presentational and simply emits values rather than acting on
23+
them itself. It is the job of the parent component to act on those values as needed.
1724

1825
<br />
1926

@@ -22,11 +29,13 @@ the parent component to act on those values as needed.
2229
- [@Inputs](#inputs)
2330
- [@Outputs](#outputs)
2431
- [The InputPasswordFlow](#the-inputpasswordflow)
32+
- [Use Cases](#use-cases)
2533
- [HTML - Form Fields](#html---form-fields)
2634
- [TypeScript - Credential Generation](#typescript---credential-generation)
2735
- [Difference between SetInitialPasswordAccountRegistration and SetInitialPasswordAuthedUser](#difference-between-setinitialpasswordaccountregistration-and-setinitialpasswordautheduser)
2836
- [Validation](#validation)
2937
- [Submit Logic](#submit-logic)
38+
- [Submitting From a Parent Dialog Component](#submitting-from-a-parent-dialog-component)
3039
- [Example](#example)
3140

3241
<br />
@@ -37,12 +46,23 @@ the parent component to act on those values as needed.
3746

3847
- `flow` - the parent component must provide an `InputPasswordFlow`, which is used to determine
3948
which form input elements will be displayed in the UI and which cryptographic keys will be created
40-
and emitted.
41-
- `email` - the parent component must provide an email so that the `InputPasswordComponent` can
42-
create a master key.
49+
and emitted. [Click here](#the-inputpasswordflow) to learn more about the different
50+
`InputPasswordFlow` options.
51+
52+
**Optional (sometimes)**
53+
54+
These two `@Inputs` are optional on some flows, but required on others. Therefore these `@Inputs`
55+
are not marked as `{ required: true }`, but there _is_ component logic that ensures (requires) that
56+
the `email` and/or `userId` is present in certain flows, while not present in other flows.
57+
58+
- `email` - allows the `InputPasswordComponent` to generate a master key
59+
- `userId` - allows the `InputPasswordComponent` to do things like get the user's `kdfConfig`,
60+
decrypt the user key, and perform validation prior to user a key rotation on the parent
4361

4462
**Optional**
4563

64+
These `@Inputs` are truly optional.
65+
4666
- `loading` - a boolean used to indicate that the parent component is performing some
4767
long-running/async operation and that the form should be disabled until the operation is complete.
4868
The primary button will also show a spinner if `loading` is true.
@@ -57,6 +77,7 @@ the parent component to act on those values as needed.
5777
## `@Output()`'s
5878

5979
- `onPasswordFormSubmit` - on form submit, emits a `PasswordInputResult` object
80+
([see more below](#submit-logic)).
6081
- `onSecondaryButtonClick` - on click, emits a notice that the secondary button has been clicked.
6182
The parent component can listen for this event and take some custom action as needed (go back,
6283
cancel, logout, etc.)
@@ -66,44 +87,88 @@ the parent component to act on those values as needed.
6687
## The `InputPasswordFlow`
6788

6889
The `InputPasswordFlow` is a crucial and required `@Input` that influences both the HTML and the
69-
credential generation logic of the component.
90+
credential generation logic of the component. It is important for the dev to understand when to use
91+
each flow.
7092

71-
<br />
93+
### Use Cases
7294

73-
### HTML - Form Fields
95+
**`SetInitialPasswordAccountRegistration`**
7496

75-
The `InputPasswordFlow` determines which form fields get displayed in the UI.
97+
Used in scenarios where we have no existing user, and thus NO active account `userId`:
7698

77-
**`InputPasswordFlow.SetInitialPasswordAccountRegistration`** and
78-
**`InputPasswordFlow.SetInitialPasswordAuthedUser`**
99+
- Standard Account Registration
100+
- Email Invite Account Registration
101+
- Trial Initiation Account registration<br /><br />
79102

80-
- Input: New password
81-
- Input: Confirm new password
82-
- Input: Hint
83-
- Checkbox: Check for breaches
103+
**`SetInitialPasswordAuthedUser`**
84104

85-
**`InputPasswordFlow.ChangePassword`**
105+
Used in scenarios where we do have an existing and authed user, and thus an active account `userId`:
86106

87-
Includes everything above, plus:
107+
- A "just-in-time" (JIT) provisioned user joins a master password (MP) encryption org and must set
108+
their initial password
109+
- A "just-in-time" (JIT) provisioned user joins a trusted device encryption (TDE) org with a
110+
starting role that requires them to have/set their initial password
111+
- A note on JIT provisioned user flows:
112+
- Even though a JIT provisioned user is a brand-new user who was “just” created, we consider
113+
them to be an “existing authed user” _from the perspective of the set-password flow_. This is
114+
because at the time they set their initial password, their account already exists in the
115+
database (before setting their password) and they have already authenticated via SSO.
116+
- The same is not true in the account registration flows above&mdash;that is, during account
117+
registration when a user reaches the `/finish-signup` or `/trial-initiation` page to set their
118+
initial password, their account does not yet exist in the database, and will only be created
119+
once they set an initial password.
120+
- An existing user in a TDE org logs in after the org admin upgraded the user to a role that now
121+
requires them to have/set their initial password
122+
- An existing user logs in after their org admin offboarded the org from TDE, and the user must now
123+
have/set their initial password<br /><br />
88124

89-
- Input: Current password (as the first element in the UI)
125+
**`ChangePassword`**
90126

91-
**`InputPasswordFlow.ChangePasswordWithOptionalUserKeyRotation`**
127+
Used in scenarios where a we simply want simply offer the user the ability to change their password:
92128

93-
Includes everything above, plus:
129+
- User clicks an org email invite link an logs in with their password which does not meet the org's
130+
policy requirements
131+
- User logs in with password that does not meet the org's policy requirements
132+
- User logs in after their password was reset via Account Recovery (and now they must change their
133+
password)<br /><br />
134+
135+
**`ChangePasswordWithOptionalUserKeyRotation`**
136+
137+
Used in scenarios where we want to offer users the additional option of rotating their user key:
138+
139+
- Account Settings (Web) - change password screen
140+
141+
Note that the user key rotation itself does not happen on the `InputPasswordComponent`, but rather
142+
on the parent component. The `InputPasswordComponent` simply emits a boolean value that indicates
143+
whether or not the user key should be rotated.<br /><br />
144+
145+
**`ChangePasswordDelegation`**
146+
147+
Used in scenarios where one user changes the password for another user's account:
148+
149+
- Emergency Access Takeover
150+
- Account Recovery<br /><br />
151+
152+
### HTML - Form Fields
94153

95-
- Checkbox: Rotate account encryption key (as the last element in the UI)
154+
Click through the individual Stories in Storybook to see how the `InputPassswordFlow` determines
155+
which form field UI elements get displayed.
96156

97157
<br />
98158

99159
### TypeScript - Credential Generation
100160

101-
- The `SetInitialPasswordAccountRegistration` and `SetInitialPasswordAuthedUser` flows involve a
102-
user setting their password for the first time. Therefore on submit the component will only
103-
generate new credentials (`newMasterKey`) and not current credentials (`currentMasterKey`).
104-
- The `ChangePassword` and `ChangePasswordWithOptionalUserKeyRotation` flows both require the user
105-
to enter a current password along with a new password. Therefore on submit the component will
106-
generate current credentials (`currentMasterKey`) along with new credentials (`newMasterKey`).
161+
- **`SetInitialPasswordAccountRegistration`** and **`SetInitialPasswordAuthedUser`**
162+
- These flows involve a user setting their password for the first time. Therefore on submit the
163+
component will only generate new credentials (`newMasterKey`) and not current credentials
164+
(`currentMasterKey`).<br /><br />
165+
- **`ChangePassword`** and **`ChangePasswordWithOptionalUserKeyRotation`**
166+
- These flows both require the user to enter a current password along with a new password.
167+
Therefore on submit the component will generate current credentials (`currentMasterKey`) along
168+
with new credentials (`newMasterKey`).<br /><br />
169+
- **`ChangePasswordDelegation`**
170+
- This flow does not generate any credentials, but simply validates the new password and emits it
171+
up to the parent.
107172

108173
<br />
109174

@@ -114,32 +179,8 @@ credentials, but we need to keep them separate for the following reasons:
114179

115180
- `SetInitialPasswordAccountRegistration` involves scenarios where we have no existing user, and
116181
**thus NO active account `userId`**:
117-
118-
- Standard Account Registration
119-
- Email Invite Account Registration
120-
- Trial Initiation Account Registration
121-
122-
<br />
123-
124182
- `SetInitialPasswordAuthedUser` involves scenarios where we do have an existing and authed user,
125183
and **thus an active account `userId`**:
126-
- A "just-in-time" (JIT) provisioned user joins a master password (MP) encryption org and must set
127-
their initial password
128-
- A "just-in-time" (JIT) provisioned user joins a trusted device encryption (TDE) org with a
129-
starting role that requires them to have/set their initial password
130-
- A note on JIT provisioned user flows:
131-
- Even though a JIT provisioned user is a brand-new user who was “just” created, we consider
132-
them to be an “existing authed user” _from the perspective of the set-password flow_. This
133-
is because at the time they set their initial password, their account already exists in the
134-
database (before setting their password) and they have already authenticated via SSO.
135-
- The same is not true in the account registration flows above&mdash;that is, during account
136-
registration when a user reaches the `/finish-signup` or `/trial-initiation` page to set
137-
their initial password, their account does not yet exist in the database, and will only be
138-
created once they set an initial password.
139-
- An existing user in a TDE org logs in after the org admin upgraded the user to a role that now
140-
requires them to have/set their initial password
141-
- An existing user logs in after their org admin offboarded the org from TDE, and the user must
142-
now have/set their initial password
143184

144185
The presence or absence of an active account `userId` is important because it determines how we get
145186
the correct `kdfConfig` prior to key generation:
@@ -170,11 +211,6 @@ Form validators ensure that:
170211
- The new password and confirmed new password are the same
171212
- The new password and password hint are NOT the same
172213

173-
Additional submit logic validation ensures that:
174-
175-
- The new password adheres to any enforced master password policy options (that were passed down
176-
from the parent)
177-
178214
<br />
179215

180216
## Submit Logic
@@ -183,9 +219,10 @@ When the form is submitted, the `InputPasswordComponent` does the following in o
183219

184220
1. Verifies inputs:
185221
- Checks that the current password is correct (if it was required in the flow)
186-
- Checks if the new password is found in a breach and warns the user if so (if the user selected
187-
the checkbox)
188-
- Checks that the new password meets any master password policy requirements enforced by an org
222+
- Checks that the new password is not weak or found in any breaches (if the user selected the
223+
checkbox)
224+
- Checks that the new password adheres to any enforced master password policies that were
225+
optionally passed down by the parent
189226
2. Uses the form inputs to create cryptographic properties (`newMasterKey`,
190227
`newServerMasterKeyHash`, etc.)
191228
3. Emits those cryptographic properties up to the parent (along with other values defined in
@@ -209,6 +246,67 @@ export interface PasswordInputResult {
209246
}
210247
```
211248

249+
## Submitting From a Parent Dialog Component
250+
251+
Some of our set/change password flows use dialogs, such as Emergency Access Takeover and Account
252+
Recovery. These are covered by the `ChangePasswordDelegation` flow. Because dialogs have their own
253+
buttons, we don't want to display an additional Submit button in the `InputPasswordComponent` when
254+
embedded a dialog.
255+
256+
Therefore we do the following:
257+
258+
- The `InputPasswordComponent` hides the button in the UI and exposes its `submit()` method as a
259+
public method.
260+
- The parent dialog component can then access this method via `@ViewChild()`.
261+
- When the user clicks the primary button on the parent dialog, we call the `submit()` method on the
262+
`InputPasswordComponent`.
263+
264+
```html
265+
<!-- emergency-access-takeover-dialog.component.html -->
266+
267+
<bit-dialog dialogSize="large">
268+
<span bitDialogTitle><!-- ... --></span>
269+
270+
<div bitDialogContent>
271+
<auth-input-password
272+
[flow]="inputPasswordFlow"
273+
[masterPasswordPolicyOptions]="masterPasswordPolicyOptions"
274+
(onPasswordFormSubmit)="handlePasswordFormSubmit($event)"
275+
></auth-input-password>
276+
</div>
277+
278+
<ng-container bitDialogFooter>
279+
<button type="button" bitButton buttonType="primary" (click)="handlePrimaryButtonClick()">
280+
{{ "save" | i18n }}
281+
</button>
282+
<button type="button" bitButton buttonType="secondary" bitDialogClose>
283+
{{ "cancel" | i18n }}
284+
</button>
285+
</ng-container>
286+
</bit-dialog>
287+
```
288+
289+
```typescript
290+
// emergency-access-takeover-dialog.component.ts
291+
292+
export class EmergencyAccessTakeoverDialogComponent implements OnInit {
293+
@ViewChild(InputPasswordComponent)
294+
inputPasswordComponent: InputPasswordComponent;
295+
296+
// ...
297+
298+
handlePrimaryButtonClick = async () => {
299+
await this.inputPasswordComponent.submit();
300+
};
301+
302+
async handlePasswordFormSubmit(passwordInputResult: PasswordInputResult) {
303+
// ... run logic that handles the `PasswordInputResult` object emission
304+
}
305+
}
306+
```
307+
308+
<br />
309+
212310
# Example
213311

214312
**`InputPasswordFlow.ChangePasswordWithOptionalUserKeyRotation`**

0 commit comments

Comments
 (0)