Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking โ€œSign up for GitHubโ€, you agree to our terms of service and privacy statement. Weโ€™ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PM-3301] Login - Move incorrect username or password error to inline field error #11443

Closed
Changes from 1 commit
Commits
Show all changes
159 commits
Select commit Hold shift + click to select a range
af9483d
setup new LoginComponent files in libs/auth
rr-bw Aug 20, 2024
2d60073
Merge branch 'main' into auth/pm-8111/browser-refresh-login-component
rr-bw Aug 21, 2024
af91d39
update pageTitle
rr-bw Aug 21, 2024
2b90cbb
handle loading email settings
rr-bw Aug 21, 2024
d4213fb
setup web-login.service.ts
rr-bw Aug 22, 2024
d917426
implement web onInit
rr-bw Aug 23, 2024
fcf01fe
Merge branch 'main' into auth/pm-8111/browser-refresh-login-component
rr-bw Aug 26, 2024
688a24b
fill out webOnInit
rr-bw Aug 27, 2024
97f9008
refactor getOrgPolicies call
rr-bw Aug 27, 2024
a5fec36
update import
rr-bw Aug 27, 2024
669585a
merge main
rr-bw Aug 30, 2024
9b28a0e
add validateEmail logic
rr-bw Aug 30, 2024
2a58a69
handle registerRoute
rr-bw Aug 30, 2024
621115a
add showPasswordless flag
rr-bw Aug 30, 2024
0cd840e
handle captcha
rr-bw Aug 31, 2024
983cee8
handle startAuthRequestLogin()
rr-bw Aug 31, 2024
19acf12
add handleMigrateEncryptionKey to default and web service
rr-bw Sep 2, 2024
48ffd0b
handle submit routing (web)
rr-bw Sep 2, 2024
1ad35b0
fix typo
rr-bw Sep 2, 2024
d74561d
merge main, fix conflicts
rr-bw Sep 5, 2024
d279ae4
Merge branch 'main' into auth/pm-8111/browser-refresh-login-component
rr-bw Sep 7, 2024
e190ca4
incorporate loginEmailService changes
rr-bw Sep 7, 2024
4f893e0
minor updates to comments for clarity
rr-bw Sep 7, 2024
e8c4217
create a defaultOnInit()
rr-bw Sep 7, 2024
70d15fb
update defaultOnInit()
rr-bw Sep 7, 2024
00a29b3
handle master password input focus
rr-bw Sep 9, 2024
3636c72
handle post-login routing on Browser/Desktop
rr-bw Sep 9, 2024
3c68fb0
handle browser/desktop syncService
rr-bw Sep 9, 2024
81a623d
handle browser ngOnInit
rr-bw Sep 9, 2024
bdd6f9f
handle browser routing and basic browser template
rr-bw Sep 9, 2024
4d1ab66
setup desktop router
rr-bw Sep 9, 2024
b564ff4
Merge branch 'main' into auth/pm-8111/browser-refresh-login-component
rr-bw Sep 9, 2024
e8e5ec2
add template for desktop first UI state: email entry
rr-bw Sep 9, 2024
b997b60
rename 'response' to 'authResult'
rr-bw Sep 10, 2024
40e2cb5
refactor handleMigrateEncryptionKey()
rr-bw Sep 10, 2024
7d8886e
refactor captcha methods and add return types
rr-bw Sep 10, 2024
feb16c3
refactor submit logic
rr-bw Sep 10, 2024
d098ee0
refactor submit logic further to use if statements with returns insteโ€ฆ
rr-bw Sep 10, 2024
9588148
remove toast error on invalid form for Browser/Desktop
rr-bw Sep 10, 2024
0826184
refactor to handleAuthResult() method
rr-bw Sep 10, 2024
d76f483
refactor webOnInit
rr-bw Sep 10, 2024
ff53fee
add comment to revisit ngOnInit logic
rr-bw Sep 10, 2024
b64552f
refactor handlCaptchaRequired()
rr-bw Sep 10, 2024
e2434ff
create a LoginSecondaryContentComponent for AnonLayout use
rr-bw Sep 10, 2024
04ca091
minor formatting for consistency
rr-bw Sep 11, 2024
0f62f07
add clarifying comment to handleAuthResult()
rr-bw Sep 11, 2024
8c78662
minor refactor to use destructuring
rr-bw Sep 11, 2024
c597b92
setup desktopOnInit()
rr-bw Sep 11, 2024
167b246
add continue() method
rr-bw Sep 11, 2024
e3219d2
handle desktop ngOnDestroy()
rr-bw Sep 11, 2024
b0f4ac1
add clarifying comment regarding secondary content
rr-bw Sep 11, 2024
234191e
fill out desktop template and submit()
rr-bw Sep 11, 2024
96f31ec
add descriptive comment to top of HTML file
rr-bw Sep 11, 2024
f9dc912
refactor to use a uiState enum for UI states
rr-bw Sep 11, 2024
c89eb92
handle oss-routing swap
rr-bw Sep 12, 2024
677829f
handle registerRoute$ in secondary content
rr-bw Sep 12, 2024
0cf965c
web template modifications
rr-bw Sep 12, 2024
8696330
change email validation to only run on submit (or when clicking contiโ€ฆ
rr-bw Sep 12, 2024
6ffaeae
add dynamic anon-layout wrapper data
rr-bw Sep 12, 2024
bb5f88f
remove static element ref
rr-bw Sep 12, 2024
7a4b83a
desktop HTML template updates
rr-bw Sep 12, 2024
9cb64b5
remove 'showPassword' property b/c now handled by bitPasswordInputToggle
rr-bw Sep 12, 2024
e616218
Extension: setup EmailEntry state UI
rr-bw Sep 12, 2024
350459f
Extension: setup MasterPasswordEntry state UI
rr-bw Sep 12, 2024
de4b177
merge main, fix conflicts
rr-bw Sep 13, 2024
4012a6c
ensure full sync happens on all clients before navigation
rr-bw Sep 13, 2024
c446345
update icon stroke color
rr-bw Sep 13, 2024
532d3ea
change old components to V1
rr-bw Sep 13, 2024
8fa5c55
remove 'V2' from new component
rr-bw Sep 13, 2024
80fd8bd
update captcha iframe on all clients
rr-bw Sep 13, 2024
236c41e
add browser redirect from /home to /login with FF on
rr-bw Sep 13, 2024
4df7712
add todo comment regarding browser template
rr-bw Sep 13, 2024
b799618
add launchSsoBrowser to extension template
rr-bw Sep 13, 2024
e076e94
move extension launchSsoBrowserWindow() to extension service
rr-bw Sep 14, 2024
66072f6
cleanup & comments
rr-bw Sep 14, 2024
da18b42
add launchSsoBrowserWindow() to default service
rr-bw Sep 14, 2024
d88606a
setup launchSsoBrowserWindow() for Desktop
rr-bw Sep 14, 2024
e0d4702
refactor to use toastService
rr-bw Sep 14, 2024
d49c044
remove unnecessary service injection
rr-bw Sep 14, 2024
0bb18eb
rename LoginService to LoginComponentService to avoid confusion with โ€ฆ
rr-bw Sep 14, 2024
6bbbfcd
add jsdocs to LoginComponentService
rr-bw Sep 14, 2024
6d1d02a
rename loginService prop to loginComponentService
rr-bw Sep 14, 2024
54f0c0a
Add vault icon to anon layout.
alec-livefront Sep 23, 2024
c37f726
Prevent email address validation on blur.
alec-livefront Sep 24, 2024
9bb8409
Fix comment typo.
alec-livefront Sep 24, 2024
d9f930d
Prefill email field when "create account" is clicked.
alec-livefront Sep 24, 2024
74767b0
Use factory function to provide LoginEmailService.
alec-livefront Sep 25, 2024
22eb2aa
Merge branch 'main' into auth/pm-8111/browser-refresh-login-component
alec-livefront Sep 25, 2024
9a6b1a9
Add test for RegisterFormComponent.
alec-livefront Sep 25, 2024
e0eff02
Remove back button todo.
alec-livefront Sep 25, 2024
3187a33
Consolidate clearing loginEmailService values and routing
alec-livefront Sep 25, 2024
7767545
Remove unnecessary navigation.
alec-livefront Sep 25, 2024
1206017
Fix client navigation after login.
alec-livefront Sep 25, 2024
7f14851
Consolidate login templates.
alec-livefront Sep 25, 2024
a1b9216
Break up LoginComponent into client-specific services.
alec-livefront Sep 26, 2024
309576f
Merge branch 'main' into auth/pm-8111/browser-refresh-login-component
alec-livefront Sep 26, 2024
588a7af
Rename login.component to login-v1.component
alec-livefront Sep 26, 2024
9a277d6
Rename login.component to login-v1.component
alec-livefront Sep 26, 2024
5628ad4
Revert "Rename login.component to login-v1.component"
alec-livefront Sep 26, 2024
2e6e5a5
Revert "Rename login.component to login-v1.component"
alec-livefront Sep 26, 2024
035e62e
Rename login.component to login-v1.component except browser.
alec-livefront Sep 26, 2024
60d1177
Comment out debug code.
alec-livefront Sep 26, 2024
a97dc74
Remove debug code.
alec-livefront Sep 26, 2024
e607aa7
Rename login.component to login-v1.component for browser.
alec-livefront Sep 26, 2024
07f1419
Add login-with-passkey route to desktop.
alec-livefront Sep 26, 2024
4ead4ef
Set feature flag to false.
alec-livefront Sep 26, 2024
c062970
Fix linting errors.
alec-livefront Sep 27, 2024
bf8312d
Populate email on registration start form.
alec-livefront Sep 27, 2024
bb67f56
Implement email population on all clients add add safeProviders.
alec-livefront Sep 27, 2024
30af195
Remove comment re. passing email to registration.
alec-livefront Sep 27, 2024
58d6770
Add unauthUiRefreshRedirect utility function.
alec-livefront Sep 27, 2024
b2a63e6
Add transparent border.
alec-livefront Sep 30, 2024
3140be2
Merge branch 'main' into auth/pm-8111/browser-refresh-login-component
alec-livefront Sep 30, 2024
fbb5e35
Merge branch 'main' of https://github.com/bitwarden/clients
alec-livefront Sep 30, 2024
7190f4d
Merge branch 'main' into auth/pm-8111/browser-refresh-login-component
alec-livefront Sep 30, 2024
ea8cd09
Merge main and add satisfies RouteDataProperties
alec-livefront Sep 30, 2024
79b2633
PM-8111 - Extension - AppRoutingModule - Home route now redirects conโ€ฆ
JaredSnider-Bitwarden Sep 30, 2024
d1a0c2f
PM-8111 - New Login Comp + Login Comp Svc - (1) Refactor naming and rโ€ฆ
JaredSnider-Bitwarden Sep 30, 2024
04fa618
PM-8111 - TODO cleanup
JaredSnider-Bitwarden Sep 30, 2024
8469e35
PM-8111 - (1) Cleanup DefaultLoginComponentService (2) Sso Connector โ€ฆ
JaredSnider-Bitwarden Sep 30, 2024
86a10f2
PM-8111 - Two TODO cleanups
JaredSnider-Bitwarden Sep 30, 2024
a104a92
Remove specific client services.
alec-livefront Oct 1, 2024
ca0520c
Add isLoginWithPasskeySupported function to reduce client type checkiโ€ฆ
alec-livefront Oct 1, 2024
4f11c2c
Add styles missing from Browser to Create Account link.
alec-livefront Oct 1, 2024
f42a391
Confirmed inline form errors working and removing todo comments.
alec-livefront Oct 1, 2024
2d5f4df
Convert refactoring todo-rr-bw to standard todos.
alec-livefront Oct 1, 2024
d47ffdf
Add login component services tests.
alec-livefront Oct 2, 2024
bdc988c
Cleanup formatting and remove unused provider.
alec-livefront Oct 2, 2024
f8f8bb5
Add comment to explain call to setLoginEmail.
alec-livefront Oct 2, 2024
c0d37bc
Merge branch 'main' into auth/pm-8111/browser-refresh-login-component
alec-livefront Oct 2, 2024
66536d4
Rearrange imports to fix lint error.
alec-livefront Oct 2, 2024
9308a47
Merge branch 'main' into auth/pm-8111/browser-refresh-login-component
alec-livefront Oct 3, 2024
68f358b
Merge branch 'main' into auth/pm-8111/browser-refresh-login-component
alec-livefront Oct 4, 2024
f6d59dc
Adjust styles for password hint link.
alec-livefront Oct 4, 2024
db7b45f
Merge branch 'main' into auth/pm-8111/browser-refresh-login-component
alec-livefront Oct 4, 2024
cead261
Merge branch 'main' into auth/pm-8111/browser-refresh-login-component
alec-livefront Oct 4, 2024
51e8614
Show master password error inline.
alec-livefront Oct 7, 2024
0df9474
Merge branch 'main' into auth/pm-8111/browser-refresh-login-component
alec-livefront Oct 7, 2024
467d773
Remove new error handling from v1 component.
alec-livefront Oct 7, 2024
d1a5455
Merge branch 'main' into auth/pm-8111/browser-refresh-login-component
alec-livefront Oct 8, 2024
994e097
Address PR feedback: use strict comparison.
alec-livefront Oct 8, 2024
2bb89a4
Ensure Login with Passkey button is shown by setting clientType.
alec-livefront Oct 9, 2024
5aec3e8
Update "continue" button from "submit" to "button" type.
alec-livefront Oct 9, 2024
8975b60
Ensure Passkey login available for web and desktop.
alec-livefront Oct 9, 2024
57044a6
Validate email on enter keypress.
alec-livefront Oct 9, 2024
6e337e1
Use click event to trigger goToHint.
alec-livefront Oct 9, 2024
47ce605
Restructure handAuthResult to ensure we redirect to vault.
alec-livefront Oct 9, 2024
6d980bf
Add await to saveEmailSettings function.
alec-livefront Oct 9, 2024
982da46
Directly set clientType in individual login component services.
alec-livefront Oct 9, 2024
3868dcb
Get clientType via service.
alec-livefront Oct 10, 2024
90a24cb
Merge branch 'main' into auth/pm-8111/browser-refresh-login-component
alec-livefront Oct 10, 2024
ea68572
Add back button.
alec-livefront Oct 10, 2024
1b17ddc
Merge branch 'main' into auth/pm-8111/browser-refresh-login-component
alec-livefront Oct 10, 2024
9b20322
Remove hardcoded colors from Vault Icon
alec-livefront Oct 10, 2024
7533089
Removing register component changes.
alec-livefront Oct 10, 2024
99ddbc9
Removing register component changes.
alec-livefront Oct 10, 2024
3936ccd
Ensure isLoginWithPasskeySupported is only returns true for web client.
alec-livefront Oct 10, 2024
72f07fe
Remove Web/Desktop comment from html template
alec-livefront Oct 10, 2024
a2fa009
Merge branch 'auth/pm-8111/browser-refresh-login-component' into authโ€ฆ
alec-livefront Oct 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
desktop HTML template updates
rr-bw committed Sep 12, 2024
commit 7a4b83afdedd4dc18b08357f1e11219d68cc55c8
3 changes: 3 additions & 0 deletions apps/desktop/src/locales/en/messages.json
Original file line number Diff line number Diff line change
@@ -517,6 +517,9 @@
"logInWithPasskey": {
"message": "Log in with passkey"
},
"loginWithDevice": {
"message": "Log in with device"
},
"or": {
"message": "or"
},
87 changes: 39 additions & 48 deletions libs/auth/src/angular/login/login.component.html
Original file line number Diff line number Diff line change
@@ -37,7 +37,7 @@
<div class="tw-grid tw-gap-3">
<!-- Continue button -->
<button type="submit" bitButton block buttonType="primary" (click)="validateEmail()">
<span>{{ "continue" | i18n }}</span>
{{ "continue" | i18n }}
</button>

<div class="tw-text-center">{{ "or" | i18n }}</div>
@@ -50,7 +50,8 @@
routerLink="/login-with-passkey"
(mousedown)="$event.preventDefault()"
>
<span><i class="bwi bwi-passkey"></i>{{ "logInWithPasskey" | i18n }}</span>
<i class="bwi bwi-passkey tw-mr-1"></i>
{{ "logInWithPasskey" | i18n }}
</a>

<!-- Link to Login with SSO page -->
@@ -62,7 +63,7 @@
[queryParams]="{ email: formGroup.value.email }"
(click)="saveEmailSettings()"
>
<i class="bwi bwi-provider"></i>
<i class="bwi bwi-provider tw-mr-1"></i>
{{ "useSingleSignOn" | i18n }}
</a>
</div>
@@ -93,9 +94,9 @@
</div>

<div class="tw-grid tw-gap-3">
<!-- Button to Login with Master Password -->
<!-- Submit button to Login with Master Password -->
<button type="submit" bitButton bitFormButton block buttonType="primary">
<span>{{ "loginWithMasterPassword" | i18n }}</span>
{{ "loginWithMasterPassword" | i18n }}
</button>

<!-- Button to Login with Device -->
@@ -109,7 +110,8 @@
buttonType="secondary"
(click)="startAuthRequestLogin()"
>
<span><i class="bwi bwi-mobile"></i>{{ "loginWithDevice" | i18n }}</span>
<i class="bwi bwi-mobile"></i>
{{ "loginWithDevice" | i18n }}
</button>
</ng-container>
</div>
@@ -127,12 +129,9 @@
<!-- Desktop Template -->
<!---------------------------------------------->
<form *ngIf="clientType === ClientType.Desktop" [bitSubmit]="submit" [formGroup]="formGroup">
<!---------------------------------
Desktop UI State 1: Email Entry
---------------------------------->
<ng-container *ngIf="!validatedEmail">
<ng-container *ngIf="uiState === LoginUiState.EMAIL_ENTRY">
<!-- Email Address input -->
<bit-form-field>
<bit-form-field class="!tw-mb-4">
<bit-label>{{ "emailAddress" | i18n }}</bit-label>
<input
type="email"
@@ -144,67 +143,58 @@
</bit-form-field>

<!-- Remember Email input -->
<bit-form-control>
<bit-form-control class="!tw-mb-4">
<input type="checkbox" formControlName="rememberEmail" bitCheckbox />
<bit-label>{{ "rememberEmail" | i18n }}</bit-label>
</bit-form-control>

<div class="tw-grid tw-gap-3">
<!-- Continue button -->
<button type="submit" bitButton buttonType="primary" (click)="continue()">
<span> {{ "continue" | i18n }} </span>
{{ "continue" | i18n }}
</button>

<div class="tw-text-center">{{ "or" | i18n }}</div>

<!-- Link to Login with Passkey page -->
<button type="button" bitButton block buttonType="secondary" routerLink="/login-with-passkey">
<span><i class="bwi bwi-passkey"></i> {{ "logInWithPasskey" | i18n }}</span>
<i class="bwi bwi-passkey tw-mr-1"></i>
{{ "logInWithPasskey" | i18n }}
</button>

<!-- Link to SSO page -->
<button type="button" bitButton block buttonType="secondary" routerLink="/sso">
<span><i class="bwi bwi-provider"></i> {{ "useSingleSignOn" | i18n }}</span>
<i class="bwi bwi-provider tw-mr-1"></i>
{{ "useSingleSignOn" | i18n }}
</button>
</div>

<!--
TODO-rr-bw: in the secondary content ("New to Bitwarden? Create account"), which is
now being added via app-routing.module.ts, consider if you need to use `registerRoute$ | async
as in the current desktop login component.
-->
</ng-container>

<!-------------------------------------------
Desktop UI State 2: Master Password Entry
-------------------------------------------->

<ng-container *ngIf="validatedEmail">
<div class="tw-grid tw-gap-4">
<div>
<!-- Master Password input -->
<bit-form-field class="!tw-mb-1">
<bit-label>{{ "masterPassword" | i18n }}</bit-label>
<input type="password" formControlName="masterPassword" bitInput />
<button type="button" bitIconButton bitSuffix bitPasswordInputToggle></button>
</bit-form-field>

<!-- Link to Password Hint page -->
<a
class="tw-font-semibold"
routerLink="/hint"
(mousedown)="goToHint()"
(click)="saveEmailSettings()"
>
{{ "getMasterPasswordHint" | i18n }}
</a>
</div>
<ng-container *ngIf="uiState === LoginUiState.MASTER_PASSWORD_ENTRY">
<!-- Master Password input -->
<bit-form-field class="!tw-mb-1">
<bit-label>{{ "masterPassword" | i18n }}</bit-label>
<input type="password" formControlName="masterPassword" bitInput />
<button type="button" bitIconButton bitSuffix bitPasswordInputToggle></button>
</bit-form-field>

<!-- Button to Login with Master Password -->
<!-- Link to Password Hint page -->
<a
class="tw-inline-block tw-mb-4 tw-font-semibold"
routerLink="/hint"
(mousedown)="goToHint()"
(click)="saveEmailSettings()"
>
{{ "getMasterPasswordHint" | i18n }}
</a>

<div class="tw-grid tw-gap-3">
<!-- Submit button to Login with Master Password -->
<button type="submit" bitButton bitFormButton block buttonType="primary">
<span> {{ "loginWithMasterPassword" | i18n }} </span>
{{ "loginWithMasterPassword" | i18n }}
</button>

<!-- Button to Login with Device -->
<ng-container *ngIf="showLoginWithDevice && showPasswordless">
<div class="tw-text-center">{{ "or" | i18n }}</div>

@@ -215,7 +205,8 @@
buttonType="secondary"
(click)="startAuthRequestLogin()"
>
<span><i class="bwi bwi-mobile"></i> {{ "loginWithDevice" | i18n }}</span>
<i class="bwi bwi-mobile"></i>
{{ "loginWithDevice" | i18n }}
</button>
</ng-container>
</div>

Unchanged files with check annotations Beta

import { DefaultLoginService, LoginService } from "@bitwarden/auth/angular";

Check warning on line 1 in apps/browser/src/auth/popup/login/extension-login.service.ts

Codecov / codecov/patch

apps/browser/src/auth/popup/login/extension-login.service.ts#L1

Added line #L1 was not covered by tests
import { flagEnabled } from "../../../platform/flags"; // TODO-rr-bw: do I need a client specific `flagEnabled()` fn?

Check warning on line 3 in apps/browser/src/auth/popup/login/extension-login.service.ts

Codecov / codecov/patch

apps/browser/src/auth/popup/login/extension-login.service.ts#L3

Added line #L3 was not covered by tests
export class ExtensionLoginService extends DefaultLoginService implements LoginService {

Check warning on line 5 in apps/browser/src/auth/popup/login/extension-login.service.ts

Codecov / codecov/patch

apps/browser/src/auth/popup/login/extension-login.service.ts#L5

Added line #L5 was not covered by tests
getShowPasswordlessFlag(): boolean {
return flagEnabled("showPasswordless");

Check warning on line 7 in apps/browser/src/auth/popup/login/extension-login.service.ts

Codecov / codecov/patch

apps/browser/src/auth/popup/login/extension-login.service.ts#L7

Added line #L7 was not covered by tests
}
}
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";

Check warning on line 5 in apps/browser/src/popup/app-routing.module.ts

Codecov / codecov/patch

apps/browser/src/popup/app-routing.module.ts#L4-L5

Added lines #L4 - L5 were not covered by tests
import {
authGuard,
lockGuard,
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";

Check warning on line 32 in apps/browser/src/popup/app-routing.module.ts

Codecov / codecov/patch

apps/browser/src/popup/app-routing.module.ts#L32

Added line #L32 was not covered by tests
import { HintComponent } from "../auth/popup/hint.component";
import { HomeComponent } from "../auth/popup/home.component";
import { LockComponent } from "../auth/popup/lock.component";
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";

Check warning on line 5 in apps/desktop/src/app/app-routing.module.ts

Codecov / codecov/patch

apps/desktop/src/app/app-routing.module.ts#L4-L5

Added lines #L4 - L5 were not covered by tests
import {
authGuard,
lockGuard,
import { AcceptOrganizationInviteService } from "../../../organization-invite/accept-organization.service";
export class WebLoginService extends DefaultLoginService implements LoginService {
acceptOrganizationInviteService = inject(AcceptOrganizationInviteService);
logService = inject(LogService);
policyApiService = inject(PolicyApiServiceAbstraction);
policyService = inject(InternalPolicyService);
router = inject(Router);
routerService = inject(RouterService);

Check warning on line 21 in apps/web/src/app/auth/core/services/login/web-login.service.ts

Codecov / codecov/patch

apps/web/src/app/auth/core/services/login/web-login.service.ts#L16-L21

Added lines #L16 - L21 were not covered by tests
getShowPasswordlessFlag(): boolean {
return flagEnabled("showPasswordless");

Check warning on line 24 in apps/web/src/app/auth/core/services/login/web-login.service.ts

Codecov / codecov/patch

apps/web/src/app/auth/core/services/login/web-login.service.ts#L24

Added line #L24 was not covered by tests
}
setPreviousUrl(route: UrlTree): void | null {
this.routerService.setPreviousUrl(route.toString());

Check warning on line 28 in apps/web/src/app/auth/core/services/login/web-login.service.ts

Codecov / codecov/patch

apps/web/src/app/auth/core/services/login/web-login.service.ts#L28

Added line #L28 was not covered by tests
}
async getOrgPolicies(): Promise<PasswordPolicies | null> {
const orgInvite = await this.acceptOrganizationInviteService.getOrganizationInvite();

Check warning on line 32 in apps/web/src/app/auth/core/services/login/web-login.service.ts

Codecov / codecov/patch

apps/web/src/app/auth/core/services/login/web-login.service.ts#L32

Added line #L32 was not covered by tests
if (orgInvite != null) {
let policies: Policy[];
try {
policies = await this.policyApiService.getPoliciesByToken(

Check warning on line 38 in apps/web/src/app/auth/core/services/login/web-login.service.ts

Codecov / codecov/patch

apps/web/src/app/auth/core/services/login/web-login.service.ts#L37-L38

Added lines #L37 - L38 were not covered by tests
orgInvite.organizationId,
orgInvite.token,
orgInvite.email,
orgInvite.organizationUserId,
);
} catch (e) {
this.logService.error(e);

Check warning on line 45 in apps/web/src/app/auth/core/services/login/web-login.service.ts

Codecov / codecov/patch

apps/web/src/app/auth/core/services/login/web-login.service.ts#L45

Added line #L45 was not covered by tests
}
if (policies == null) {
return;

Check warning on line 49 in apps/web/src/app/auth/core/services/login/web-login.service.ts

Codecov / codecov/patch

apps/web/src/app/auth/core/services/login/web-login.service.ts#L49

Added line #L49 was not covered by tests
}
const resetPasswordPolicy = this.policyService.getResetPasswordPolicyOptions(

Check warning on line 52 in apps/web/src/app/auth/core/services/login/web-login.service.ts

Codecov / codecov/patch

apps/web/src/app/auth/core/services/login/web-login.service.ts#L52

Added line #L52 was not covered by tests
policies,
orgInvite.organizationId,
);
const isPolicyAndAutoEnrollEnabled =
resetPasswordPolicy[1] && resetPasswordPolicy[0].autoEnrollEnabled;
const enforcedPasswordPolicyOptions = await firstValueFrom(

Check warning on line 60 in apps/web/src/app/auth/core/services/login/web-login.service.ts

Codecov / codecov/patch

apps/web/src/app/auth/core/services/login/web-login.service.ts#L60

Added line #L60 was not covered by tests
this.policyService.masterPasswordPolicyOptions$(policies),
);
return {

Check warning on line 64 in apps/web/src/app/auth/core/services/login/web-login.service.ts

Codecov / codecov/patch

apps/web/src/app/auth/core/services/login/web-login.service.ts#L64

Added line #L64 was not covered by tests
policies,
isPolicyAndAutoEnrollEnabled,
enforcedPasswordPolicyOptions,
import { NgModule } from "@angular/core";
import { Route, RouterModule, Routes } from "@angular/router";
import { unauthUiRefreshSwap } from "@bitwarden/angular/auth/functions/unauth-ui-refresh-route-swap";

Check warning on line 4 in apps/web/src/app/oss-routing.module.ts

Codecov / codecov/patch

apps/web/src/app/oss-routing.module.ts#L4

Added line #L4 was not covered by tests
import {
authGuard,
lockGuard,
export * from "./bitwarden-logo.icon";
export * from "./bitwarden-shield.icon";
export * from "./lock.icon";
export * from "./registration-check-email.icon";
export * from "./registration-expired-link.icon";

Check warning on line 5 in libs/auth/src/angular/icons/index.ts

Codecov / codecov/patch

libs/auth/src/angular/icons/index.ts#L4-L5

Added lines #L4 - L5 were not covered by tests
export * from "./user-verification-biometrics-fingerprint.icon";
export * from "./wave.icon";

Check warning on line 7 in libs/auth/src/angular/icons/index.ts

Codecov / codecov/patch

libs/auth/src/angular/icons/index.ts#L7

Added line #L7 was not covered by tests
import { svgIcon } from "@bitwarden/components";

Check warning on line 1 in libs/auth/src/angular/icons/wave.icon.ts

Codecov / codecov/patch

libs/auth/src/angular/icons/wave.icon.ts#L1

Added line #L1 was not covered by tests
export const WaveIcon = svgIcon`

Check warning on line 3 in libs/auth/src/angular/icons/wave.icon.ts

Codecov / codecov/patch

libs/auth/src/angular/icons/wave.icon.ts#L3

Added line #L3 was not covered by tests
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="98" fill="none">
<path class="tw-stroke-text-headers" stroke-linejoin="round" stroke-width="2" d="M38.604 48.08c.187-.341.364-.688.565-1.022 4.409-7.312 8.826-14.62 13.228-21.936 2.132-3.54.317-7.806-3.688-8.72-2.335-.533-4.775.562-6.204 2.844-2.923 4.673-5.823 9.362-8.731 14.043-2.2 3.542-4.385 7.094-6.61 10.62-1.844 2.926-4.231 5.315-7.246 7.035-1.851 1.057-2.841.543-3.121-1.554-.549-4.105-1.185-8.194-2.446-12.155-1.625-5.1-6.98-7.558-11.908-5.469-1.135.482-1.362.949-1.092 2.137.703 3.086 1.53 6.152 2.061 9.27.789 4.638.402 9.275-.4 13.894a90.853 90.853 0 0 0-1.353 14.404c-.062 4.798 1.476 8.947 4.825 12.337 3.654 3.702 7.422 7.313 11.932 9.989 7.128 4.23 14.349 4.162 21.606.282 3.89-2.08 7.272-4.84 10.478-7.827 8.69-8.101 5.227-5.375 16.07-11.488 4.702-2.65 9.436-5.242 14.152-7.863 2.707-1.505 3.593-4.521 2.145-7.276-1.399-2.666-4.426-3.627-7.186-2.228-6.594 3.345-13.173 6.717-19.76 10.076-.325.165-.651.323-1.085.344.372-.304.734-.619 1.116-.91 7.578-5.801 15.158-11.601 22.737-17.401 1.86-1.425 2.714-3.3 2.344-5.624-.359-2.26-1.707-3.769-3.872-4.483-1.898-.626-3.629-.245-5.258.928-7.792 5.607-15.604 11.188-23.41 16.776-.274.196-.55.389-.974.452.234-.278.454-.572.705-.835 7.24-7.632 14.493-15.25 21.72-22.893 3.355-3.549 1.622-9.313-3.127-10.382-2.274-.512-4.275.06-5.935 1.796-7.056 7.373-14.134 14.721-21.197 22.087-.294.306-.51.686-.765 1.031-.105-.093-.212-.185-.316-.278Z"/>
<path class="tw-stroke-text-headers" stroke-linecap="round" stroke-width="2" d="M39.237 1.496c-13.4 0-24.262 10.863-24.262 24.262"/>
export * from "./fingerprint-dialog/fingerprint-dialog.component";
// icons
export * from "./icons";

Check warning on line 15 in libs/auth/src/angular/index.ts

Codecov / codecov/patch

libs/auth/src/angular/index.ts#L15

Added line #L15 was not covered by tests
// input password
export * from "./input-password/input-password.component";
export * from "./input-password/password-input-result";
// login
export * from "./login/login.component";
export * from "./login/login-secondary-content.component";
export * from "./login/login.service";
export * from "./login/default-login.service";

Check warning on line 25 in libs/auth/src/angular/index.ts

Codecov / codecov/patch

libs/auth/src/angular/index.ts#L22-L25

Added lines #L22 - L25 were not covered by tests
// password callout
export * from "./password-callout/password-callout.component";

Check warning on line 28 in libs/auth/src/angular/index.ts

Codecov / codecov/patch

libs/auth/src/angular/index.ts#L28

Added line #L28 was not covered by tests
// registration
export * from "./registration/registration-start/registration-start.component";
export * from "./registration/registration-finish/default-registration-finish.service";
// set password (JIT user)
export * from "./set-password-jit/set-password-jit.component";
export * from "./set-password-jit/set-password-jit.service.abstraction";
export * from "./set-password-jit/default-set-password-jit.service";

Check warning on line 42 in libs/auth/src/angular/index.ts

Codecov / codecov/patch

libs/auth/src/angular/index.ts#L40-L42

Added lines #L40 - L42 were not covered by tests
// user verification
export * from "./user-verification/user-verification-dialog.component";
export * from "./user-verification/user-verification-dialog.types";
export * from "./user-verification/user-verification-form-input.component";

Check warning on line 47 in libs/auth/src/angular/index.ts

Codecov / codecov/patch

libs/auth/src/angular/index.ts#L45-L47

Added lines #L45 - L47 were not covered by tests
// vault timeout input
export * from "./vault-timeout-input/vault-timeout-input.component";

Check warning on line 50 in libs/auth/src/angular/index.ts

Codecov / codecov/patch

libs/auth/src/angular/index.ts#L50

Added line #L50 was not covered by tests
import { LoginService, PasswordPolicies } from "./login.service";
export class DefaultLoginService implements LoginService {

Check warning on line 8 in libs/auth/src/angular/login/default-login.service.ts

Codecov / codecov/patch

libs/auth/src/angular/login/default-login.service.ts#L8

Added line #L8 was not covered by tests
constructor(
protected i18nService: I18nService,
protected toastService: ToastService,

Check warning on line 11 in libs/auth/src/angular/login/default-login.service.ts

Codecov / codecov/patch

libs/auth/src/angular/login/default-login.service.ts#L10-L11

Added lines #L10 - L11 were not covered by tests
) {}
getShowPasswordlessFlag(): boolean {
return null;

Check warning on line 15 in libs/auth/src/angular/login/default-login.service.ts

Codecov / codecov/patch

libs/auth/src/angular/login/default-login.service.ts#L15

Added line #L15 was not covered by tests
}
setPreviousUrl(route: UrlTree): void | null {
return null;

Check warning on line 19 in libs/auth/src/angular/login/default-login.service.ts

Codecov / codecov/patch

libs/auth/src/angular/login/default-login.service.ts#L19

Added line #L19 was not covered by tests
}
async getOrgPolicies(): Promise<PasswordPolicies | null> {
return null;

Check warning on line 23 in libs/auth/src/angular/login/default-login.service.ts

Codecov / codecov/patch

libs/auth/src/angular/login/default-login.service.ts#L23

Added line #L23 was not covered by tests
}
}
import { CommonModule } from "@angular/common";
import { Component, inject } from "@angular/core";
import { RouterModule } from "@angular/router";

Check warning on line 3 in libs/auth/src/angular/login/login-secondary-content.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login-secondary-content.component.ts#L1-L3

Added lines #L1 - L3 were not covered by tests
import { JslibModule } from "@bitwarden/angular/jslib.module";
import { RegisterRouteService } from "@bitwarden/auth/common";

Check warning on line 6 in libs/auth/src/angular/login/login-secondary-content.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login-secondary-content.component.ts#L5-L6

Added lines #L5 - L6 were not covered by tests
@Component({
standalone: true,
</div>
`,
})
export class LoginSecondaryContentComponent {
registerRouteService = inject(RegisterRouteService);

Check warning on line 21 in libs/auth/src/angular/login/login-secondary-content.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login-secondary-content.component.ts#L20-L21

Added lines #L20 - L21 were not covered by tests
// TODO: remove when email verification flag is removed
protected registerRoute$ = this.registerRouteService.registerRoute$();

Check warning on line 24 in libs/auth/src/angular/login/login-secondary-content.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login-secondary-content.component.ts#L24

Added line #L24 was not covered by tests
// TODO-rr-bw: In the original login implementation, the "Create account" link
// also passes the email address to the registration page. We need to find a way to
import { CommonModule } from "@angular/common";
import { Component, ElementRef, Input, NgZone, OnDestroy, OnInit, ViewChild } from "@angular/core";
import { FormBuilder, FormControl, ReactiveFormsModule, Validators } from "@angular/forms";
import { ActivatedRoute, Router, RouterModule } from "@angular/router";
import { first, firstValueFrom, of, Subject, switchMap, take, takeUntil } from "rxjs";

Check warning on line 5 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L1-L5

Added lines #L1 - L5 were not covered by tests
import { JslibModule } from "@bitwarden/angular/jslib.module";
import {

Check warning on line 8 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L7-L8

Added lines #L7 - L8 were not covered by tests
LoginEmailServiceAbstraction,
LoginStrategyServiceAbstraction,
PasswordLoginCredentials,
RegisterRouteService,
} from "@bitwarden/auth/common";
import { InternalPolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
import { PolicyData } from "@bitwarden/common/admin-console/models/data/policy.data";

Check warning on line 15 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L14-L15

Added lines #L14 - L15 were not covered by tests
import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options";
import { Policy } from "@bitwarden/common/admin-console/models/domain/policy";
import { DevicesApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices-api.service.abstraction";
import { CaptchaIFrame } from "@bitwarden/common/auth/captcha-iframe";

Check warning on line 19 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L18-L19

Added lines #L18 - L19 were not covered by tests
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
import { ClientType } from "@bitwarden/common/enums";
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { Utils } from "@bitwarden/common/platform/misc/utils";
import { SyncService } from "@bitwarden/common/platform/sync";
import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength";

Check warning on line 31 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L21-L31

Added lines #L21 - L31 were not covered by tests
import { UserId } from "@bitwarden/common/types/guid";
import {

Check warning on line 33 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L33

Added line #L33 was not covered by tests
AsyncActionsModule,
ButtonModule,
CheckboxModule,
ToastService,
} from "@bitwarden/components";
import { AnonLayoutWrapperDataService } from "../anon-layout/anon-layout-wrapper-data.service";
import { WaveIcon } from "../icons";

Check warning on line 43 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L42-L43

Added lines #L42 - L43 were not covered by tests
import { LoginService } from "./login.service";

Check warning on line 45 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L45

Added line #L45 was not covered by tests
const BroadcasterSubscriptionId = "LoginComponent";

Check warning on line 47 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L47

Added line #L47 was not covered by tests
export enum LoginUiState {
EMAIL_ENTRY = "EmailEntry",
MASTER_PASSWORD_ENTRY = "MasterPasswordEntry",

Check warning on line 51 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L50-L51

Added lines #L50 - L51 were not covered by tests
}
@Component({
RouterModule,
],
})
export class LoginComponentV2 implements OnInit, OnDestroy {

Check warning on line 69 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L69

Added line #L69 was not covered by tests
@ViewChild("masterPasswordInputRef") masterPasswordInputRef: ElementRef;
@Input() captchaSiteKey: string = null;

Check warning on line 71 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L71

Added line #L71 was not covered by tests
private destroy$ = new Subject<void>();
readonly Icons = { WaveIcon };

Check warning on line 74 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L73-L74

Added lines #L73 - L74 were not covered by tests
captcha: CaptchaIFrame;
captchaToken: string = null;

Check warning on line 77 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L77

Added line #L77 was not covered by tests
clientType: ClientType;
ClientType = ClientType;
LoginUiState = LoginUiState;
registerRoute$ = this.registerRouteService.registerRoute$(); // TODO: remove when email verification flag is removed
showLoginWithDevice = false;
validatedEmail = false;

Check warning on line 83 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L79-L83

Added lines #L79 - L83 were not covered by tests
formGroup = this.formBuilder.group({

Check warning on line 85 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L85

Added line #L85 was not covered by tests
email: ["", [Validators.required, Validators.email]],
masterPassword: [
"",
});
get emailFormControl(): FormControl<string> {
return this.formGroup.controls.email;

Check warning on line 95 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L95

Added line #L95 was not covered by tests
}
get loggedEmail(): string {
return this.formGroup.value.email;

Check warning on line 99 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L99

Added line #L99 was not covered by tests
}
get uiState(): LoginUiState {
// Web properties
enforcedPasswordPolicyOptions: MasterPasswordPolicyOptions;
policies: Policy[];
showPasswordless = false;
showResetPasswordAutoEnrollWarning = false;

Check warning on line 110 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L109-L110

Added lines #L109 - L110 were not covered by tests
// Desktop properties
deferFocus: boolean = null; // TODO-rr-bw: why initialize to null instead of false
showPassword = false; // TODO-rr-bw: is this still needed? It seems we no longer need this now that we have bitPasswordInputToggle

Check warning on line 114 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L113-L114

Added lines #L113 - L114 were not covered by tests
constructor(
private activatedRoute: ActivatedRoute,
private registerRouteService: RegisterRouteService,
private router: Router,
private syncService: SyncService,
private toastService: ToastService,

Check warning on line 136 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L136

Added line #L136 was not covered by tests
) {
this.clientType = this.platformUtilsService.getClientType();
this.showPasswordless = this.loginService.getShowPasswordlessFlag();

Check warning on line 139 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L138-L139

Added lines #L138 - L139 were not covered by tests
}
async ngOnInit(): Promise<void> {
if (this.clientType === ClientType.Web) {
await this.webOnInit();

Check warning on line 144 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L144

Added line #L144 was not covered by tests
}
await this.defaultOnInit();

Check warning on line 147 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L147

Added line #L147 was not covered by tests
if (this.clientType === ClientType.Browser) {
if (this.showPasswordless) {
await this.validateEmail();

Check warning on line 151 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L151

Added line #L151 was not covered by tests
}
}
if (this.clientType === ClientType.Desktop) {
await this.desktopOnInit();

Check warning on line 156 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L156

Added line #L156 was not covered by tests
}
}
ngOnDestroy(): void {
if (this.clientType === ClientType.Desktop) {
// TODO-rr-bw: refactor to not use deprecated broadcaster service.
this.broadcasterService.unsubscribe(BroadcasterSubscriptionId);

Check warning on line 163 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L163

Added line #L163 was not covered by tests
}
this.destroy$.next();
this.destroy$.complete();

Check warning on line 167 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L166-L167

Added lines #L166 - L167 were not covered by tests
}
submit = async (): Promise<void> => {

Check warning on line 170 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L170

Added line #L170 was not covered by tests
if (this.clientType === ClientType.Desktop) {
if (!this.validatedEmail) {
return;

Check warning on line 173 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L173

Added line #L173 was not covered by tests
}
}
const { email, masterPassword } = this.formGroup.value;

Check warning on line 177 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L177

Added line #L177 was not covered by tests
await this.setupCaptcha();

Check warning on line 179 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L179

Added line #L179 was not covered by tests
/**
* TODO-rr-bw: Verify the following
*
* Therefore below I am simply checking if the form is invalid and returning if so.
*/
this.formGroup.markAllAsTouched();

Check warning on line 196 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L196

Added line #L196 was not covered by tests
if (this.formGroup.invalid) {
return;

Check warning on line 198 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L198

Added line #L198 was not covered by tests
}
const credentials = new PasswordLoginCredentials(

Check warning on line 201 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L201

Added line #L201 was not covered by tests
email,
masterPassword,
this.captchaToken,
null,
);
const authResult = await this.loginStrategyService.logIn(credentials);

Check warning on line 208 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L208

Added line #L208 was not covered by tests
await this.saveEmailSettings();
await this.handleAuthResult(authResult);

Check warning on line 211 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L210-L211

Added lines #L210 - L211 were not covered by tests
if (this.clientType === ClientType.Desktop) {
if (this.captchaSiteKey) {
const content = document.getElementById("content") as HTMLDivElement;
content.setAttribute("style", "width:335px");

Check warning on line 216 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L215-L216

Added lines #L215 - L216 were not covered by tests
}
}
};
*/
private async handleAuthResult(authResult: AuthResult): Promise<void> {
if (this.handleCaptchaRequired(authResult)) {
this.captchaSiteKey = authResult.captchaSiteKey;
this.captcha.init(authResult.captchaSiteKey);
return;

Check warning on line 233 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L231-L233

Added lines #L231 - L233 were not covered by tests
}
if (authResult.requiresEncryptionKeyMigration) {
/* Legacy accounts used the master key to encrypt data.
Migration is required but only performed on Web. */
if (this.clientType === ClientType.Web) {
await this.router.navigate(["migrate-legacy-encryption"]);

Check warning on line 240 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L240

Added line #L240 was not covered by tests
} else {
this.toastService.showToast({

Check warning on line 242 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L242

Added line #L242 was not covered by tests
variant: "error",
title: this.i18nService.t("errorOccured"),
message: this.i18nService.t("encryptionKeyMigrationRequired"),
});
}
return;

Check warning on line 248 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L248

Added line #L248 was not covered by tests
}
if (authResult.requiresTwoFactor) {
await this.router.navigate(["2fa"]);
return;

Check warning on line 253 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L252-L253

Added lines #L252 - L253 were not covered by tests
}
if (authResult.forcePasswordReset != ForceSetPasswordReason.None) {
this.loginEmailService.clearValues();
await this.router.navigate(["update-temp-password"]);
return;

Check warning on line 259 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L257-L259

Added lines #L257 - L259 were not covered by tests
}
// If none of the above cases are true, proceed with login...
// ...on Web
if (this.clientType === ClientType.Web) {
await this.goAfterLogIn(authResult.userId);
return;

Check warning on line 266 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L265-L266

Added lines #L265 - L266 were not covered by tests
// ...on Browser/Desktop
} else {
await this.syncService.fullSync(true); // TODO-rr-bw: browser used `await`, desktop used `return`. Why? Does it matter?
this.loginEmailService.clearValues();

Check warning on line 271 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L270-L271

Added lines #L270 - L271 were not covered by tests
if (this.clientType === ClientType.Browser) {
await this.router.navigate(["/tabs/vault"]);

Check warning on line 274 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L274

Added line #L274 was not covered by tests
} else {
await this.router.navigate(["vault"]); // Desktop

Check warning on line 276 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L276

Added line #L276 was not covered by tests
}
return;

Check warning on line 278 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L278

Added line #L278 was not covered by tests
}
}
protected async goAfterLogIn(userId: UserId): Promise<void> {
const masterPassword = this.formGroup.value.masterPassword;

Check warning on line 283 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L283

Added line #L283 was not covered by tests
// Check master password against policy
if (this.enforcedPasswordPolicyOptions != null) {
const strengthResult = this.passwordStrengthService.getPasswordStrength(

Check warning on line 287 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L287

Added line #L287 was not covered by tests
masterPassword,
this.formGroup.value.email,
);
this.enforcedPasswordPolicyOptions,
)
) {
const policiesData: { [id: string]: PolicyData } = {};
this.policies.map((p) => (policiesData[p.id] = PolicyData.fromPolicy(p)));
await this.policyService.replace(policiesData, userId);
await this.router.navigate(["update-password"]);
return;

Check warning on line 305 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L301-L305

Added lines #L301 - L305 were not covered by tests
}
}
/* TODO-rr-bw: these two lines are also used at the end of the submit method for
Browser/Desktop. See if you can consolidate for all 3 clients. */
this.loginEmailService.clearValues();
await this.router.navigate(["vault"]);

Check warning on line 312 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L311-L312

Added lines #L311 - L312 were not covered by tests
}
protected showCaptcha(): boolean {
return !Utils.isNullOrWhitespace(this.captchaSiteKey);

Check warning on line 316 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L316

Added line #L316 was not covered by tests
}
protected async startAuthRequestLogin(): Promise<void> {
this.formGroup.get("masterPassword")?.updateValueAndValidity();
if (!this.formGroup.valid) {
return;

Check warning on line 324 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L324

Added line #L324 was not covered by tests
}
await this.saveEmailSettings();
await this.router.navigate(["/login-with-device"]);

Check warning on line 328 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L327-L328

Added lines #L327 - L328 were not covered by tests
}
protected async validateEmail(): Promise<void> {
this.formGroup.controls.email.markAsTouched();
const emailValid = this.formGroup.controls.email.valid;

Check warning on line 333 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L332-L333

Added lines #L332 - L333 were not covered by tests
if (emailValid) {
this.toggleValidateEmail(true);
await this.getLoginWithDevice(this.loggedEmail);

Check warning on line 337 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L336-L337

Added lines #L336 - L337 were not covered by tests
this.anonLayoutWrapperDataService.setAnonLayoutWrapperData({

Check warning on line 339 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L339

Added line #L339 was not covered by tests
pageTitle: "welcomeBack",
pageSubtitle: {
// TODO-rr-bw: add an icon that takes the user back
}
protected toggleValidateEmail(value: boolean): void {
this.validatedEmail = value;

Check warning on line 352 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L352

Added line #L352 was not covered by tests
if (!this.validatedEmail) {
// Reset master password only when going from validated to not validated so that autofill can work properly
this.formGroup.controls.masterPassword.reset();

Check warning on line 356 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L356

Added line #L356 was not covered by tests
} else {
// Mark MP as untouched so that, when users enter email and hit enter, the MP field doesn't load with validation errors
this.formGroup.controls.masterPassword.markAsUntouched();

Check warning on line 359 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L359

Added line #L359 was not covered by tests
// When email is validated, focus on master password after waiting for input to be rendered
if (this.ngZone.isStable) {
this.masterPasswordInputRef?.nativeElement?.focus();
} else {
this.ngZone.onStable.pipe(take(1), takeUntil(this.destroy$)).subscribe(() => {

Check warning on line 365 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L365

Added line #L365 was not covered by tests
this.masterPasswordInputRef?.nativeElement?.focus();
});
}
}
protected async goToHint(): Promise<void> {
await this.saveEmailSettings();
await this.router.navigateByUrl("/hint");

Check warning on line 374 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L373-L374

Added lines #L373 - L374 were not covered by tests
}
protected async goToRegister(): Promise<void> {
// TODO: remove when email verification flag is removed
const registerRoute = await firstValueFrom(this.registerRoute$);

Check warning on line 379 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L379

Added line #L379 was not covered by tests
if (this.emailFormControl.valid) {
await this.router.navigate([registerRoute], {

Check warning on line 382 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L382

Added line #L382 was not covered by tests
queryParams: { email: this.emailFormControl.value },
});
return;

Check warning on line 385 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L385

Added line #L385 was not covered by tests
}
await this.router.navigate([registerRoute]);

Check warning on line 388 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L388

Added line #L388 was not covered by tests
}
protected async saveEmailSettings(): Promise<void> {
this.loginEmailService.setLoginEmail(this.formGroup.value.email);
this.loginEmailService.setRememberEmail(this.formGroup.value.rememberEmail);
await this.loginEmailService.saveEmailSettings();

Check warning on line 394 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L392-L394

Added lines #L392 - L394 were not covered by tests
}
protected async continue(): Promise<void> {
await this.validateEmail();

Check warning on line 398 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L398

Added line #L398 was not covered by tests
if (!this.formGroup.controls.email.valid) {
this.toastService.showToast({

Check warning on line 401 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L401

Added line #L401 was not covered by tests
variant: "error",
title: this.i18nService.t("errorOccured"),
message: this.i18nService.t("invalidEmail"),
});
return;

Check warning on line 406 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L406

Added line #L406 was not covered by tests
}
this.focusInput();

Check warning on line 409 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L409

Added line #L409 was not covered by tests
}
private async getLoginWithDevice(email: string): Promise<void> {
try {
const deviceIdentifier = await this.appIdService.getAppId();
this.showLoginWithDevice = await this.devicesApiService.getKnownDevice(

Check warning on line 415 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L413-L415

Added lines #L413 - L415 were not covered by tests
email,
deviceIdentifier,
);
} catch (e) {
this.showLoginWithDevice = false;

Check warning on line 420 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L420

Added line #L420 was not covered by tests
}
}
private async setupCaptcha(): Promise<void> {
const env = await firstValueFrom(this.environmentService.environment$);
const webVaultUrl = env.getWebVaultUrl();

Check warning on line 426 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L425-L426

Added lines #L425 - L426 were not covered by tests
this.captcha = new CaptchaIFrame(

Check warning on line 428 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L428

Added line #L428 was not covered by tests
window,
webVaultUrl,
this.i18nService,
(token: string) => {
this.captchaToken = token;

Check warning on line 433 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L433

Added line #L433 was not covered by tests
},
(error: string) => {
this.toastService.showToast({

Check warning on line 436 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L436

Added line #L436 was not covered by tests
variant: "error",
title: this.i18nService.t("errorOccurred"),
message: error,
});
},
(info: string) => {
this.toastService.showToast({

Check warning on line 443 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L443

Added line #L443 was not covered by tests
variant: "info",
title: this.i18nService.t("info"),
message: info,
}
private handleCaptchaRequired(authResult: AuthResult): boolean {
return !Utils.isNullOrWhitespace(authResult.captchaSiteKey);

Check warning on line 453 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L453

Added line #L453 was not covered by tests
}
private async loadEmailSettings(): Promise<void> {
// Try to load the email from memory first
const email = await firstValueFrom(this.loginEmailService.loginEmail$);
const rememberEmail = this.loginEmailService.getRememberEmail();

Check warning on line 459 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L458-L459

Added lines #L458 - L459 were not covered by tests
if (email) {
this.formGroup.controls.email.setValue(email);
this.formGroup.controls.rememberEmail.setValue(rememberEmail);

Check warning on line 463 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L462-L463

Added lines #L462 - L463 were not covered by tests
} else {
// If there is no email in memory, check for a storedEmail on disk
const storedEmail = await firstValueFrom(this.loginEmailService.storedEmail$);

Check warning on line 466 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L466

Added line #L466 was not covered by tests
if (storedEmail) {
this.formGroup.controls.email.setValue(storedEmail);

Check warning on line 469 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L469

Added line #L469 was not covered by tests
// If there is a storedEmail, rememberEmail defaults to true
this.formGroup.controls.rememberEmail.setValue(true);

Check warning on line 471 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L471

Added line #L471 was not covered by tests
}
}
}
private onWindowHidden() {
this.showPassword = false;

Check warning on line 477 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L477

Added line #L477 was not covered by tests
}
private focusInput() {
const email = this.loggedEmail;

Check warning on line 481 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L481

Added line #L481 was not covered by tests
document.getElementById(email == null || email === "" ? "email" : "masterPassword")?.focus();
}
private async defaultOnInit(): Promise<void> {
let paramEmailIsSet = false;

Check warning on line 486 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L486

Added line #L486 was not covered by tests
this.activatedRoute?.queryParams
.pipe(
switchMap((params) => {
if (!params) {
// If no params,loadEmailSettings from state
return this.loadEmailSettings();

Check warning on line 493 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L493

Added line #L493 was not covered by tests
}
const qParamsEmail = params.email;

Check warning on line 496 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L496

Added line #L496 was not covered by tests
// If there is an email in the query params, set that email as the form field value
if (qParamsEmail != null && qParamsEmail.indexOf("@") > -1) {
this.formGroup.controls.email.setValue(qParamsEmail);
paramEmailIsSet = true;

Check warning on line 501 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L500-L501

Added lines #L500 - L501 were not covered by tests
}
// If there is no email in the query params, loadEmailSettings from state
// Backup check to handle unknown case where activatedRoute is not available
// This shouldn't happen under normal circumstances
if (!this.activatedRoute) {
await this.loadEmailSettings();

Check warning on line 514 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L514

Added line #L514 was not covered by tests
}
}
private async webOnInit(): Promise<void> {
this.activatedRoute.queryParams.pipe(first(), takeUntil(this.destroy$)).subscribe((qParams) => {

Check warning on line 519 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L519

Added line #L519 was not covered by tests
// If there is a parameter called 'org', set previousUrl to `/create-organization?org=<paramValue>`
if (qParams.org != null) {
const route = this.router.createUrlTree(["create-organization"], {

Check warning on line 522 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L522

Added line #L522 was not covered by tests
queryParams: { plan: qParams.org },
});
this.loginService.setPreviousUrl(route);

Check warning on line 525 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L525

Added line #L525 was not covered by tests
}
/**
* Therefore set the prevousUrl to `/setup/families-for-enterprise?token=<paramValue>`
*/
if (qParams.sponsorshipToken != null) {
const route = this.router.createUrlTree(["setup/families-for-enterprise"], {

Check warning on line 533 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L533

Added line #L533 was not covered by tests
queryParams: { token: qParams.sponsorshipToken },
});
this.loginService.setPreviousUrl(route);

Check warning on line 536 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L536

Added line #L536 was not covered by tests
}
});
* logic here BEFORE the defaultOnInit() call.
*/
// If there's an existing org invite, use it to get the password policies
const orgPolicies = await this.loginService.getOrgPolicies();

Check warning on line 548 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L548

Added line #L548 was not covered by tests
this.policies = orgPolicies?.policies;
this.showResetPasswordAutoEnrollWarning = orgPolicies?.isPolicyAndAutoEnrollEnabled;
}
private async desktopOnInit(): Promise<void> {
await this.getLoginWithDevice(this.loggedEmail);

Check warning on line 556 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L556

Added line #L556 was not covered by tests
// TODO-rr-bw: refactor to not use deprecated broadcaster service.
this.broadcasterService.subscribe(BroadcasterSubscriptionId, async (message: any) => {
this.ngZone.run(() => {

Check warning on line 560 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L559-L560

Added lines #L559 - L560 were not covered by tests
switch (message.command) {
case "windowHidden":
this.onWindowHidden();
break;

Check warning on line 564 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L563-L564

Added lines #L563 - L564 were not covered by tests
case "windowIsFocused":
if (this.deferFocus === null) {
this.deferFocus = !message.windowIsFocused;

Check warning on line 567 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L567

Added line #L567 was not covered by tests
if (!this.deferFocus) {
this.focusInput();

Check warning on line 569 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L569

Added line #L569 was not covered by tests
}
} else if (this.deferFocus && message.windowIsFocused) {
this.focusInput();
this.deferFocus = false;

Check warning on line 573 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L572-L573

Added lines #L572 - L573 were not covered by tests
}
break;

Check warning on line 575 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L575

Added line #L575 was not covered by tests
default:
}
});
});
this.messagingService.send("getWindowIsFocused");

Check warning on line 581 in libs/auth/src/angular/login/login.component.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.component.ts#L581

Added line #L581 was not covered by tests
}
}
enforcedPasswordPolicyOptions: MasterPasswordPolicyOptions;
}
export abstract class LoginService {

Check warning on line 12 in libs/auth/src/angular/login/login.service.ts

Codecov / codecov/patch

libs/auth/src/angular/login/login.service.ts#L12

Added line #L12 was not covered by tests
// Web specific
getShowPasswordlessFlag: () => boolean;
getOrgPolicies: () => Promise<PasswordPolicies | null>;