Skip to content

Commit

Permalink
[PM-8116] Auth Browser Refresh: Password Hint Component (#10492)
Browse files Browse the repository at this point in the history
* setup component, services, and web HTML

* make Web and Browser functional

* make desktop functional

* update template to solidify common client HTML

* simplify template and class

* update browser routing

* move canActivate to correct location

* simplify post submit routing

* update routing to use unauthUiRefreshSwap()

* constrain AnonLayout title/subtitle width, reduce height on destkop to account for header

* reduce height on browser to account for header (otherwise have to scroll to see EnvSelector

* resolve email issue when clicking 'cancel' on extension popout

* update routing for web

* persist email to popout

* update web router and anon-layout min-h based on client

* change anchor link to button

* remove unnecessary formatting changes

* add new icon

* remove unnecessary call to loginEmailService
  • Loading branch information
rr-bw authored Sep 13, 2024
1 parent 54cc35e commit 96d116d
Show file tree
Hide file tree
Showing 15 changed files with 357 additions and 30 deletions.
12 changes: 12 additions & 0 deletions apps/browser/src/_locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,18 @@
"addItem": {
"message": "Add item"
},
"accountEmail": {
"message": "Account email"
},
"requestHint": {
"message": "Request hint"
},
"requestPasswordHint": {
"message": "Request password hint"
},
"enterYourAccountEmailAddressAndYourPasswordHintWillBeSentToYou": {
"message": "Enter your account email address and your password hint will be sent to you"
},
"passwordHint": {
"message": "Password hint"
},
Expand Down
46 changes: 40 additions & 6 deletions apps/browser/src/popup/app-routing.module.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Injectable, NgModule } from "@angular/core";
import { ActivatedRouteSnapshot, RouteReuseStrategy, RouterModule, Routes } from "@angular/router";

import { EnvironmentSelectorComponent } from "@bitwarden/angular/auth/components/environment-selector.component";
import { unauthUiRefreshSwap } from "@bitwarden/angular/auth/functions/unauth-ui-refresh-route-swap";
import {
authGuard,
lockGuard,
Expand All @@ -15,18 +17,21 @@ import { extensionRefreshSwap } from "@bitwarden/angular/utils/extension-refresh
import {
AnonLayoutWrapperComponent,
AnonLayoutWrapperData,
PasswordHintComponent,
RegistrationFinishComponent,
RegistrationStartComponent,
RegistrationStartSecondaryComponent,
RegistrationStartSecondaryComponentData,
SetPasswordJitComponent,
UserLockIcon,
} from "@bitwarden/auth/angular";
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";

import { twofactorRefactorSwap } from "../../../../libs/angular/src/utils/two-factor-component-refactor-route-swap";
import { fido2AuthGuard } from "../auth/guards/fido2-auth.guard";
import { AccountSwitcherComponent } from "../auth/popup/account-switching/account-switcher.component";
import { EnvironmentComponent } from "../auth/popup/environment.component";
import { ExtensionAnonLayoutWrapperComponent } from "../auth/popup/extension-anon-layout-wrapper/extension-anon-layout-wrapper.component";
import { HintComponent } from "../auth/popup/hint.component";
import { HomeComponent } from "../auth/popup/home.component";
import { LockComponent } from "../auth/popup/lock.component";
Expand Down Expand Up @@ -213,12 +218,6 @@ const routes: Routes = [
canActivate: [unauthGuardFn(unauthRouteOverrides)],
data: { state: "register" },
},
{
path: "hint",
component: HintComponent,
canActivate: [unauthGuardFn(unauthRouteOverrides)],
data: { state: "hint" },
},
{
path: "environment",
component: EnvironmentComponent,
Expand Down Expand Up @@ -385,6 +384,41 @@ const routes: Routes = [
canActivate: [authGuard],
data: { state: "update-temp-password" },
},
...unauthUiRefreshSwap(
HintComponent,
ExtensionAnonLayoutWrapperComponent,
{
path: "hint",
canActivate: [unauthGuardFn(unauthRouteOverrides)],
data: {
state: "hint",
},
},
{
path: "",
children: [
{
path: "hint",
canActivate: [unauthGuardFn(unauthRouteOverrides)],
data: {
pageTitle: "requestPasswordHint",
pageSubtitle: "enterYourAccountEmailAddressAndYourPasswordHintWillBeSentToYou",
pageIcon: UserLockIcon,
showBackButton: true,
state: "hint",
},
children: [
{ path: "", component: PasswordHintComponent },
{
path: "",
component: EnvironmentSelectorComponent,
outlet: "environment-selector",
},
],
},
],
},
),
{
path: "",
component: AnonLayoutWrapperComponent,
Expand Down
2 changes: 2 additions & 0 deletions apps/browser/src/popup/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { AvatarModule, ButtonModule, ToastModule } from "@bitwarden/components";
import { AccountComponent } from "../auth/popup/account-switching/account.component";
import { CurrentAccountComponent } from "../auth/popup/account-switching/current-account.component";
import { EnvironmentComponent } from "../auth/popup/environment.component";
import { ExtensionAnonLayoutWrapperComponent } from "../auth/popup/extension-anon-layout-wrapper/extension-anon-layout-wrapper.component";
import { HintComponent } from "../auth/popup/hint.component";
import { HomeComponent } from "../auth/popup/home.component";
import { LockComponent } from "../auth/popup/lock.component";
Expand Down Expand Up @@ -131,6 +132,7 @@ import "../platform/popup/locales";
HeaderComponent,
UserVerificationDialogComponent,
CurrentAccountComponent,
ExtensionAnonLayoutWrapperComponent,
],
declarations: [
ActionButtonsComponent,
Expand Down
48 changes: 47 additions & 1 deletion apps/desktop/src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { NgModule } from "@angular/core";
import { RouterModule, Routes } from "@angular/router";

import { EnvironmentSelectorComponent } from "@bitwarden/angular/auth/components/environment-selector.component";
import { unauthUiRefreshSwap } from "@bitwarden/angular/auth/functions/unauth-ui-refresh-route-swap";
import {
authGuard,
lockGuard,
Expand All @@ -12,11 +14,13 @@ import { canAccessFeature } from "@bitwarden/angular/platform/guard/feature-flag
import {
AnonLayoutWrapperComponent,
AnonLayoutWrapperData,
PasswordHintComponent,
RegistrationFinishComponent,
RegistrationStartComponent,
RegistrationStartSecondaryComponent,
RegistrationStartSecondaryComponentData,
SetPasswordJitComponent,
UserLockIcon,
} from "@bitwarden/auth/angular";
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";

Expand Down Expand Up @@ -94,7 +98,6 @@ const routes: Routes = [
canActivate: [authGuard],
},
{ path: "accessibility-cookie", component: AccessibilityCookieComponent },
{ path: "hint", component: HintComponent },
{ path: "set-password", component: SetPasswordComponent },
{ path: "sso", component: SsoComponent },
{
Expand All @@ -113,10 +116,53 @@ const routes: Routes = [
canActivate: [authGuard],
data: { titleId: "removeMasterPassword" },
},
...unauthUiRefreshSwap(
HintComponent,
AnonLayoutWrapperComponent,
{
path: "hint",
canActivate: [unauthGuardFn()],
data: {
pageTitle: "passwordHint",
titleId: "passwordHint",
},
},
{
path: "",
children: [
{
path: "hint",
canActivate: [unauthGuardFn()],
data: {
pageTitle: "requestPasswordHint",
pageSubtitle: "enterYourAccountEmailAddressAndYourPasswordHintWillBeSentToYou",
pageIcon: UserLockIcon,
state: "hint",
},
children: [
{ path: "", component: PasswordHintComponent },
{
path: "",
component: EnvironmentSelectorComponent,
outlet: "environment-selector",
},
],
},
],
},
),
{
path: "",
component: AnonLayoutWrapperComponent,
children: [
{
path: "hint",
component: PasswordHintComponent,
data: {
pageTitle: "requestPasswordHint",
pageSubtitle: "enterYourAccountEmailAddressAndYourPasswordHintWillBeSentToYou",
},
},
{
path: "signup",
canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()],
Expand Down
12 changes: 12 additions & 0 deletions apps/desktop/src/locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,18 @@
"settings": {
"message": "Settings"
},
"accountEmail": {
"message": "Account email"
},
"requestHint": {
"message": "Request hint"
},
"requestPasswordHint": {
"message": "Request password hint"
},
"enterYourAccountEmailAddressAndYourPasswordHintWillBeSentToYou": {
"message": "Enter your account email address and your password hint will be sent to you"
},
"passwordHint": {
"message": "Password hint"
},
Expand Down
67 changes: 47 additions & 20 deletions apps/web/src/app/oss-routing.module.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { NgModule } from "@angular/core";
import { Route, RouterModule, Routes } from "@angular/router";

import { unauthUiRefreshSwap } from "@bitwarden/angular/auth/functions/unauth-ui-refresh-route-swap";
import {
authGuard,
lockGuard,
Expand All @@ -12,13 +13,15 @@ import { canAccessFeature } from "@bitwarden/angular/platform/guard/feature-flag
import {
AnonLayoutWrapperComponent,
AnonLayoutWrapperData,
PasswordHintComponent,
RegistrationFinishComponent,
RegistrationStartComponent,
RegistrationStartSecondaryComponent,
RegistrationStartSecondaryComponentData,
SetPasswordJitComponent,
LockIcon,
RegistrationLinkExpiredComponent,
LockIcon,
UserLockIcon,
} from "@bitwarden/auth/angular";
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";

Expand Down Expand Up @@ -167,6 +170,49 @@ const routes: Routes = [
},
],
},
...unauthUiRefreshSwap(
AnonLayoutWrapperComponent,
AnonLayoutWrapperComponent,
{
path: "hint",
canActivate: [unauthGuardFn()],
data: {
pageTitle: "passwordHint",
titleId: "passwordHint",
},
children: [
{ path: "", component: HintComponent },
{
path: "",
component: EnvironmentSelectorComponent,
outlet: "environment-selector",
},
],
},
{
path: "",
children: [
{
path: "hint",
canActivate: [unauthGuardFn()],
data: {
pageTitle: "requestPasswordHint",
pageSubtitle: "enterYourAccountEmailAddressAndYourPasswordHintWillBeSentToYou",
pageIcon: UserLockIcon,
state: "hint",
},
children: [
{ path: "", component: PasswordHintComponent },
{
path: "",
component: EnvironmentSelectorComponent,
outlet: "environment-selector",
},
],
},
],
},
),
{
path: "",
component: AnonLayoutWrapperComponent,
Expand Down Expand Up @@ -388,25 +434,6 @@ const routes: Routes = [
},
],
},
{
path: "hint",
canActivate: [unauthGuardFn()],
data: {
pageTitle: "passwordHint",
titleId: "passwordHint",
} satisfies DataProperties & AnonLayoutWrapperData,
children: [
{
path: "",
component: HintComponent,
},
{
path: "",
component: EnvironmentSelectorComponent,
outlet: "environment-selector",
},
],
},
{
path: "remove-password",
component: RemovePasswordComponent,
Expand Down
12 changes: 12 additions & 0 deletions apps/web/src/locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -960,6 +960,18 @@
"settings": {
"message": "Settings"
},
"accountEmail": {
"message": "Account email"
},
"requestHint": {
"message": "Request hint"
},
"requestPasswordHint": {
"message": "Request password hint"
},
"enterYourAccountEmailAddressAndYourPasswordHintWillBeSentToYou": {
"message": "Enter your account email address and your password hint will be sent to you"
},
"passwordHint": {
"message": "Password hint"
},
Expand Down
1 change: 1 addition & 0 deletions libs/angular/src/auth/components/login.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ export class LoginComponent extends CaptchaProtectedComponent implements OnInit,
// Try to load from memory first
const email = await firstValueFrom(this.loginEmailService.loginEmail$);
const rememberEmail = this.loginEmailService.getRememberEmail();

if (email) {
this.formGroup.controls.email.setValue(email);
this.formGroup.controls.rememberEmail.setValue(rememberEmail);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export function unauthUiRefreshSwap(
defaultComponent: Type<any>,
refreshedComponent: Type<any>,
options: Route,
altOptions?: Route,
): Routes {
return componentRouteSwap(
defaultComponent,
Expand All @@ -29,5 +30,6 @@ export function unauthUiRefreshSwap(
return configService.getFeatureFlag(FeatureFlag.UnauthenticatedExtensionUIRefresh);
},
options,
altOptions,
);
}
8 changes: 6 additions & 2 deletions libs/auth/src/angular/anon-layout/anon-layout.component.html
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
<!-- The calc() reductions are to account for browser/desktop headers -->
<main
class="tw-flex tw-min-h-screen tw-w-full tw-mx-auto tw-flex-col tw-gap-7 tw-bg-background-alt tw-px-8 tw-pb-4 tw-text-main"
class="tw-flex tw-w-full tw-mx-auto tw-flex-col tw-gap-7 tw-bg-background-alt tw-px-8 tw-pb-4 tw-text-main"
[ngClass]="{
'tw-pt-0': decreaseTopPadding,
'tw-pt-8': !decreaseTopPadding,
'tw-relative tw-top-0': clientType === 'browser',
'tw-min-h-screen': clientType === 'web',
'tw-min-h-[calc(100vh-72px)]': clientType === 'browser',
'tw-min-h-[calc(100vh-54px)]': clientType === 'desktop',
}"
>
<bit-icon *ngIf="!hideLogo" [icon]="logo" class="tw-w-[128px] [&>*]:tw-align-top"></bit-icon>
Expand All @@ -23,6 +26,7 @@ <h1 bitTypography="h2" class="tw-mt-2 tw-hidden sm:tw-block">
{{ title }}
</h1>
</ng-container>

<div *ngIf="subtitle" class="tw-text-sm sm:tw-text-base">{{ subtitle }}</div>
</div>

Expand Down
1 change: 1 addition & 0 deletions libs/auth/src/angular/icons/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from "./bitwarden-logo.icon";
export * from "./bitwarden-shield.icon";
export * from "./lock.icon";
export * from "./user-lock.icon";
export * from "./user-verification-biometrics-fingerprint.icon";
Loading

0 comments on commit 96d116d

Please sign in to comment.