handle browser routing and basic browser template

This commit is contained in:
rr-bw 2024-09-09 14:45:55 -07:00
parent 81a623d998
commit bdd6f9f6df
No known key found for this signature in database
GPG Key ID: 3FA13C3ADEE51D5D
6 changed files with 62 additions and 9 deletions

View File

@ -756,6 +756,9 @@
"logIn": { "logIn": {
"message": "Log in" "message": "Log in"
}, },
"logInToBitwarden": {
"message": "Log in to Bitwarden"
},
"restartRegistration": { "restartRegistration": {
"message": "Restart registration" "message": "Restart registration"
}, },

View File

@ -1,6 +1,8 @@
import { Injectable, NgModule } from "@angular/core"; import { Injectable, NgModule } from "@angular/core";
import { ActivatedRouteSnapshot, RouteReuseStrategy, RouterModule, Routes } from "@angular/router"; 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 { import {
authGuard, authGuard,
lockGuard, lockGuard,
@ -14,6 +16,7 @@ import { extensionRefreshSwap } from "@bitwarden/angular/utils/extension-refresh
import { import {
AnonLayoutWrapperComponent, AnonLayoutWrapperComponent,
AnonLayoutWrapperData, AnonLayoutWrapperData,
LoginComponentV2,
RegistrationFinishComponent, RegistrationFinishComponent,
RegistrationStartComponent, RegistrationStartComponent,
RegistrationStartSecondaryComponent, RegistrationStartSecondaryComponent,
@ -26,6 +29,7 @@ import { twofactorRefactorSwap } from "../../../../libs/angular/src/utils/two-fa
import { fido2AuthGuard } from "../auth/guards/fido2-auth.guard"; import { fido2AuthGuard } from "../auth/guards/fido2-auth.guard";
import { AccountSwitcherComponent } from "../auth/popup/account-switching/account-switcher.component"; import { AccountSwitcherComponent } from "../auth/popup/account-switching/account-switcher.component";
import { EnvironmentComponent } from "../auth/popup/environment.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 { HintComponent } from "../auth/popup/hint.component";
import { HomeComponent } from "../auth/popup/home.component"; import { HomeComponent } from "../auth/popup/home.component";
import { LockComponent } from "../auth/popup/lock.component"; import { LockComponent } from "../auth/popup/lock.component";
@ -134,12 +138,6 @@ const routes: Routes = [
canActivate: [fido2AuthGuard], canActivate: [fido2AuthGuard],
data: { state: "fido2" }, data: { state: "fido2" },
}), }),
{
path: "login",
component: LoginComponent,
canActivate: [unauthGuardFn(unauthRouteOverrides)],
data: { state: "login" },
},
{ {
path: "login-with-device", path: "login-with-device",
component: LoginViaAuthRequestComponent, component: LoginViaAuthRequestComponent,
@ -385,6 +383,32 @@ const routes: Routes = [
canActivate: [authGuard], canActivate: [authGuard],
data: { state: "update-temp-password" }, data: { state: "update-temp-password" },
}, },
...unauthUiRefreshSwap(
LoginComponent,
ExtensionAnonLayoutWrapperComponent,
{
path: "login",
canActivate: [unauthGuardFn(unauthRouteOverrides)],
data: { state: "login" },
},
{
path: "",
children: [
{
path: "login",
canActivate: [unauthGuardFn(unauthRouteOverrides)],
data: {
pageTitle: "logInToBitwarden",
state: "login",
}, // TODO-rr-bw: add `satisfies DataProperties & ExtensionAnonLayoutWrapperData
children: [
{ path: "", component: LoginComponentV2 },
{ path: "", component: EnvironmentSelectorComponent, outlet: "environment-selector" },
],
},
],
},
),
{ {
path: "", path: "",
component: AnonLayoutWrapperComponent, component: AnonLayoutWrapperComponent,

View File

@ -20,6 +20,7 @@ export function unauthUiRefreshSwap(
defaultComponent: Type<any>, defaultComponent: Type<any>,
refreshedComponent: Type<any>, refreshedComponent: Type<any>,
options: Route, options: Route,
altOptions?: Route,
): Routes { ): Routes {
return componentRouteSwap( return componentRouteSwap(
defaultComponent, defaultComponent,
@ -29,5 +30,6 @@ export function unauthUiRefreshSwap(
return configService.getFeatureFlag(FeatureFlag.UnauthenticatedExtensionUIRefresh); return configService.getFeatureFlag(FeatureFlag.UnauthenticatedExtensionUIRefresh);
}, },
options, options,
altOptions,
); );
} }

View File

@ -1,4 +1,20 @@
<form [bitSubmit]="submit.bind(null, false)" [formGroup]="formGroup"> <!-- Web Template -->
<!--
TODO-rr-bw: Clarify this comment if necessary.
Why not use <form *ngIf="clientType === ClientType.Web"> to display this section?
Because this file contains 3 separate templates for Web, Browser, and Desktop. For Web,
we want access to the masterPasswordInput reference in the class file.
- If we used *ngIf, we would not be able to access the reference initially.
- Using a hidden form allows us to access the reference, because it ensures that the element
reference does exist (it's just potentially hidden instead of non-existent).
-->
<form
[ngClass]="{ 'tw-hidden': clientType !== ClientType.Web }"
[bitSubmit]="submit.bind(null, false)"
[formGroup]="formGroup"
>
<!------------------------- <!-------------------------
UI STATE 1: Email Entry UI STATE 1: Email Entry
--------------------------> -------------------------->
@ -141,3 +157,8 @@
</div> </div>
</div> </div>
</form> </form>
<!-- Browser Template -->
<form *ngIf="clientType === ClientType.Browser" [bitSubmit]="submit" [formGroup]="formGroup">
<main tabindex="-1"></main>
</form>

View File

@ -62,6 +62,7 @@ export class LoginComponentV2 implements OnInit, OnDestroy {
captcha: CaptchaIFrame; captcha: CaptchaIFrame;
captchaToken: string = null; captchaToken: string = null;
clientType: ClientType; clientType: ClientType;
ClientType = ClientType;
registerRoute$ = this.registerRouteService.registerRoute$(); // TODO: remove when email verification flag is removed registerRoute$ = this.registerRouteService.registerRoute$(); // TODO: remove when email verification flag is removed
showLoginWithDevice = false; showLoginWithDevice = false;
validatedEmail = false; validatedEmail = false;
@ -140,7 +141,7 @@ export class LoginComponentV2 implements OnInit, OnDestroy {
this.destroy$.complete(); this.destroy$.complete();
} }
submit = async (showToast: boolean): Promise<void> => { submit = async (showToast = true): Promise<void> => {
const data = this.formGroup.value; const data = this.formGroup.value;
await this.setupCaptcha(); await this.setupCaptcha();
@ -153,6 +154,8 @@ export class LoginComponentV2 implements OnInit, OnDestroy {
} }
// Web specific (end) // Web specific (end)
// TODO-rr-bw: handle toast here for Browser/Desktop? See base LoginComponent -> submit()
const credentials = new PasswordLoginCredentials( const credentials = new PasswordLoginCredentials(
data.email, data.email,
data.masterPassword, data.masterPassword,

View File

@ -74,7 +74,7 @@ export const DefaultFeatureFlagValue = {
[FeatureFlag.IdpAutoSubmitLogin]: FALSE, [FeatureFlag.IdpAutoSubmitLogin]: FALSE,
[FeatureFlag.DeviceTrustLogging]: FALSE, [FeatureFlag.DeviceTrustLogging]: FALSE,
[FeatureFlag.AuthenticatorTwoFactorToken]: FALSE, [FeatureFlag.AuthenticatorTwoFactorToken]: FALSE,
[FeatureFlag.UnauthenticatedExtensionUIRefresh]: FALSE, [FeatureFlag.UnauthenticatedExtensionUIRefresh]: true,
[FeatureFlag.EnableUpgradePasswordManagerSub]: FALSE, [FeatureFlag.EnableUpgradePasswordManagerSub]: FALSE,
[FeatureFlag.GenerateIdentityFillScriptRefactor]: FALSE, [FeatureFlag.GenerateIdentityFillScriptRefactor]: FALSE,
[FeatureFlag.EnableNewCardCombinedExpiryAutofill]: FALSE, [FeatureFlag.EnableNewCardCombinedExpiryAutofill]: FALSE,