mirror of
https://github.com/bitwarden/browser
synced 2025-12-27 05:33:59 +00:00
Two-Step Login (#3852)
* [SG-163] Two step login flow web (#3648) * two step login flow * moved code from old branch and reafctored * fixed review comments * [SG-164] Two Step Login Flow - Browser (#3793) * Add new messages * Remove SSO button from home component * Change create account button to text * Add top padding to create account link * Add email input to HomeComponent * Add continue button to email input * Add form to home component * Retreive email from state service * Redirect to login after submit * Add error message for invalid email * Remove email input from login component * Remove loggingInTo from under MP input * Style the MP hint link * Add self hosted domain to email form * Made the mp hint link bold * Add the new login button * Style app-private-mode-warning in its component * Bitwarden -> Login text change * Remove the old login button * Cancel -> Close text change * Add avatar to login header * Login -> LoginWithMasterPassword text change * Add SSO button to login screen * Add not you button * Allow all clients to use the email query param on the login component * Introduct HomeGuard * Clear remembered email when clicking Not You * Make remember email opt-in * Use formGroup.patchValue instead of directly patching individual controls * [SG-165] Desktop login flow changes (#3814) * two step login flow * moved code from old branch and reafctored * fixed review comments * Make toggleValidateEmail in base class public * Add desktop login messages * Desktop login flow changes * Fix known device api error * Only submit if email has been validated * Clear remembered email when switching accounts * Fix merge issue * Add 'login with another device' button * Remove 'log in with another device' button for now * Pin login pag content to top instead of center justified * Leave email if 'Not you?' is clicked * Continue when enter is hit on email input Co-authored-by: gbubemismith <gsmithwalter@gmail.com> * [SG-750] and [SG-751] Web two step login bug fixes (#3843) * Continue when enter is hit on email input * Mark email input as touched on 'continue' so field is validated * disable login with device on self-hosted (#3895) * [SG-753] Keep email after hint component is launched in browser (#3883) * Keep email after hint component is launched in browser * Use query params instead of state for consistency * Send email and rememberEmail to home component on navigation (#3897) * removed avatar and close button from the password screen (#3901) * [SG-781] Remove extra login page and remove rememberEmail code (#3902) * Remove browser home guard * Always remember email for browser * Remove login landing page button * [SG-782] Add login service to streamline login form data persistence (#3911) * Add login service and abstraction * Inject login service into apps * Inject and use new service in login component * Use service in hint component to prefill email * Add method in LoginService to clear service values * Add LoginService to two-factor component to clear values * make login.service variables private Co-authored-by: Gbubemi Smith <gsmith@bitwarden.com> Co-authored-by: Addison Beck <addisonbeck1@gmail.com> Co-authored-by: Robyn MacCallum <robyntmaccallum@gmail.com> Co-authored-by: gbubemismith <gsmithwalter@gmail.com>
This commit is contained in:
@@ -2028,5 +2028,20 @@
|
||||
"example": "Jun 15, 2015"
|
||||
}
|
||||
}
|
||||
},
|
||||
"loginWithMasterPassword": {
|
||||
"message": "Log in with master password"
|
||||
},
|
||||
"loggingInAs": {
|
||||
"message": "Logging in as"
|
||||
},
|
||||
"notYou": {
|
||||
"message": "Not you?"
|
||||
},
|
||||
"newAroundHere": {
|
||||
"message": "New around here?"
|
||||
},
|
||||
"rememberEmail": {
|
||||
"message": "Remember email"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
<form #form (ngSubmit)="submit()" [appApiAction]="formPromise">
|
||||
<header>
|
||||
<div class="left">
|
||||
<button type="button" routerLink="/login">{{ "cancel" | i18n }}</button>
|
||||
<button type="button" routerLink="/login">
|
||||
{{ "cancel" | i18n }}
|
||||
</button>
|
||||
</div>
|
||||
<h1 class="center">
|
||||
<span class="title">{{ "passwordHint" | i18n }}</span>
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { Component } from "@angular/core";
|
||||
import { Router } from "@angular/router";
|
||||
import { ActivatedRoute, Router } from "@angular/router";
|
||||
|
||||
import { HintComponent as BaseHintComponent } from "@bitwarden/angular/components/hint.component";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/abstractions/log.service";
|
||||
import { LoginService } from "@bitwarden/common/abstractions/login.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
|
||||
|
||||
@Component({
|
||||
@@ -17,8 +18,14 @@ export class HintComponent extends BaseHintComponent {
|
||||
platformUtilsService: PlatformUtilsService,
|
||||
i18nService: I18nService,
|
||||
apiService: ApiService,
|
||||
logService: LogService
|
||||
logService: LogService,
|
||||
private route: ActivatedRoute,
|
||||
loginService: LoginService
|
||||
) {
|
||||
super(router, i18nService, apiService, platformUtilsService, logService);
|
||||
super(router, i18nService, apiService, platformUtilsService, logService, loginService);
|
||||
|
||||
super.onSuccessfulSubmit = async () => {
|
||||
this.router.navigate([this.successRoute]);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,15 +2,28 @@
|
||||
<div class="content">
|
||||
<div class="logo-image"></div>
|
||||
<p class="lead text-center">{{ "loginOrCreateNewAccount" | i18n }}</p>
|
||||
<button type="button" class="btn primary block" routerLink="/login">
|
||||
<b>{{ "login" | i18n }}</b>
|
||||
</button>
|
||||
<button type="button" (click)="launchSsoBrowser()" class="btn block">
|
||||
<i class="bwi bwi-bank" aria-hidden="true"></i> {{ "enterpriseSingleSignOn" | i18n }}
|
||||
</button>
|
||||
<button type="button" class="btn block" routerLink="/register">
|
||||
{{ "createAccount" | i18n }}
|
||||
</button>
|
||||
<form #form [formGroup]="formGroup" (ngSubmit)="submit()">
|
||||
<div class="box">
|
||||
<div class="box-content">
|
||||
<div class="box-content-row" appBoxRow>
|
||||
<label for="email">{{ "emailAddress" | i18n }}</label>
|
||||
<input id="email" type="email" formControlName="email" appInputVerbatim="false" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer no-margin" *ngIf="selfHostedDomain">
|
||||
{{ "loggingInTo" | i18n: selfHostedDomain }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="box">
|
||||
<button type="submit" class="btn primary block">
|
||||
<b>{{ "continue" | i18n }}</b>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
<p class="createAccountLink">
|
||||
{{ "newAroundHere" | i18n }}
|
||||
<a routerLink="/register">{{ "createAccount" | i18n }}</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" routerLink="/environment" class="settings-icon">
|
||||
|
||||
@@ -1,63 +1,56 @@
|
||||
import { Component } from "@angular/core";
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { FormBuilder, Validators } from "@angular/forms";
|
||||
import { ActivatedRoute, Router } from "@angular/router";
|
||||
|
||||
import { CryptoFunctionService } from "@bitwarden/common/abstractions/cryptoFunction.service";
|
||||
import { EnvironmentService } from "@bitwarden/common/abstractions/environment.service";
|
||||
import { PasswordGenerationService } from "@bitwarden/common/abstractions/passwordGeneration.service";
|
||||
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
|
||||
import { StateService } from "@bitwarden/common/abstractions/state.service";
|
||||
import { Utils } from "@bitwarden/common/misc/utils";
|
||||
|
||||
@Component({
|
||||
selector: "app-home",
|
||||
templateUrl: "home.component.html",
|
||||
})
|
||||
export class HomeComponent {
|
||||
export class HomeComponent implements OnInit {
|
||||
loginInitiated = false;
|
||||
|
||||
formGroup = this.formBuilder.group({
|
||||
email: ["", [Validators.required, Validators.email]],
|
||||
});
|
||||
|
||||
constructor(
|
||||
protected platformUtilsService: PlatformUtilsService,
|
||||
private passwordGenerationService: PasswordGenerationService,
|
||||
private stateService: StateService,
|
||||
private cryptoFunctionService: CryptoFunctionService,
|
||||
private environmentService: EnvironmentService
|
||||
private formBuilder: FormBuilder,
|
||||
private router: Router,
|
||||
private i18nService: I18nService,
|
||||
private environmentService: EnvironmentService,
|
||||
private route: ActivatedRoute
|
||||
) {}
|
||||
async ngOnInit(): Promise<void> {
|
||||
const rememberedEmail = await this.stateService.getRememberedEmail();
|
||||
if (rememberedEmail != null) {
|
||||
this.formGroup.patchValue({ email: await this.stateService.getRememberedEmail() });
|
||||
}
|
||||
}
|
||||
|
||||
async launchSsoBrowser() {
|
||||
// Generate necessary sso params
|
||||
const passwordOptions: any = {
|
||||
type: "password",
|
||||
length: 64,
|
||||
uppercase: true,
|
||||
lowercase: true,
|
||||
numbers: true,
|
||||
special: false,
|
||||
};
|
||||
|
||||
const state =
|
||||
(await this.passwordGenerationService.generatePassword(passwordOptions)) +
|
||||
":clientId=browser";
|
||||
const codeVerifier = await this.passwordGenerationService.generatePassword(passwordOptions);
|
||||
const codeVerifierHash = await this.cryptoFunctionService.hash(codeVerifier, "sha256");
|
||||
const codeChallenge = Utils.fromBufferToUrlB64(codeVerifierHash);
|
||||
|
||||
await this.stateService.setSsoCodeVerifier(codeVerifier);
|
||||
await this.stateService.setSsoState(state);
|
||||
|
||||
let url = this.environmentService.getWebVaultUrl();
|
||||
if (url == null) {
|
||||
url = "https://vault.bitwarden.com";
|
||||
submit() {
|
||||
this.formGroup.markAllAsTouched();
|
||||
if (this.formGroup.invalid) {
|
||||
this.platformUtilsService.showToast(
|
||||
"error",
|
||||
this.i18nService.t("errorOccured"),
|
||||
this.i18nService.t("invalidEmail")
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const redirectUri = url + "/sso-connector.html";
|
||||
this.stateService.setRememberedEmail(this.formGroup.value.email);
|
||||
|
||||
// Launch browser
|
||||
this.platformUtilsService.launchUri(
|
||||
url +
|
||||
"/#/sso?clientId=browser" +
|
||||
"&redirectUri=" +
|
||||
encodeURIComponent(redirectUri) +
|
||||
"&state=" +
|
||||
state +
|
||||
"&codeChallenge=" +
|
||||
codeChallenge
|
||||
);
|
||||
this.router.navigate(["login"], { queryParams: { email: this.formGroup.value.email } });
|
||||
}
|
||||
|
||||
get selfHostedDomain() {
|
||||
return this.environmentService.hasBaseUrl() ? this.environmentService.getWebVaultUrl() : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,25 +1,12 @@
|
||||
<form #form (ngSubmit)="submit()" [appApiAction]="formPromise" [formGroup]="formGroup">
|
||||
<header>
|
||||
<div class="left">
|
||||
<button type="button" routerLink="/home">{{ "cancel" | i18n }}</button>
|
||||
</div>
|
||||
<h1 class="center">
|
||||
<span class="title">{{ "appName" | i18n }}</span>
|
||||
<h1 class="login-center">
|
||||
<span class="title">{{ "logIn" | i18n }}</span>
|
||||
</h1>
|
||||
<div class="right">
|
||||
<button type="submit" [disabled]="form.loading">
|
||||
<span [hidden]="form.loading">{{ "login" | i18n }}</span>
|
||||
<i class="bwi bwi-spinner bwi-lg bwi-spin" [hidden]="!form.loading" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
<main tabindex="-1">
|
||||
<div class="box">
|
||||
<div class="box-content">
|
||||
<div class="box-content-row" appBoxRow>
|
||||
<label for="email">{{ "emailAddress" | i18n }}</label>
|
||||
<input id="email" type="email" formControlName="email" appInputVerbatim="false" />
|
||||
</div>
|
||||
<div class="box-content-row box-content-row-flex" appBoxRow>
|
||||
<div class="row-main">
|
||||
<label for="masterPassword">{{ "masterPass" | i18n }}</label>
|
||||
@@ -52,13 +39,27 @@
|
||||
<iframe id="hcaptcha_iframe" height="80"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="button" class="btn link" routerLink="/hint" (click)="setFormValues()">
|
||||
<b>{{ "getMasterPasswordHint" | i18n }}</b>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-center text-muted" *ngIf="selfHostedDomain">
|
||||
{{ "loggingInTo" | i18n: selfHostedDomain }}
|
||||
</p>
|
||||
<p class="text-center">
|
||||
<button type="button" routerLink="/hint">{{ "getMasterPasswordHint" | i18n }}</button>
|
||||
</p>
|
||||
<app-private-mode-warning></app-private-mode-warning>
|
||||
<div class="content login-buttons">
|
||||
<button type="submit" class="btn primary block" [disabled]="form.loading">
|
||||
<span [hidden]="form.loading"
|
||||
><b>{{ "logInWithMasterPassword" | i18n }}</b></span
|
||||
>
|
||||
<i class="bwi bwi-spinner bwi-lg bwi-spin" [hidden]="!form.loading" aria-hidden="true"></i>
|
||||
</button>
|
||||
<button type="button" (click)="launchSsoBrowser()" class="btn block">
|
||||
<i class="bwi bwi-bank" aria-hidden="true"></i> {{ "enterpriseSingleSignOn" | i18n }}
|
||||
</button>
|
||||
<div class="small">
|
||||
<p class="no-margin">{{ "loggingInAs" | i18n }} {{ loggedEmail }}</p>
|
||||
<a routerLink="/home">{{ "notYou" | i18n }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</form>
|
||||
|
||||
@@ -1,27 +1,33 @@
|
||||
import { Component, NgZone } from "@angular/core";
|
||||
import { FormBuilder } from "@angular/forms";
|
||||
import { Router } from "@angular/router";
|
||||
import { ActivatedRoute, Router } from "@angular/router";
|
||||
|
||||
import { LoginComponent as BaseLoginComponent } from "@bitwarden/angular/components/login.component";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { AppIdService } from "@bitwarden/common/abstractions/appId.service";
|
||||
import { AuthService } from "@bitwarden/common/abstractions/auth.service";
|
||||
import { CryptoFunctionService } from "@bitwarden/common/abstractions/cryptoFunction.service";
|
||||
import { EnvironmentService } from "@bitwarden/common/abstractions/environment.service";
|
||||
import { FormValidationErrorsService } from "@bitwarden/common/abstractions/formValidationErrors.service";
|
||||
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/abstractions/log.service";
|
||||
import { LoginService } from "@bitwarden/common/abstractions/login.service";
|
||||
import { PasswordGenerationService } from "@bitwarden/common/abstractions/passwordGeneration.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
|
||||
import { StateService } from "@bitwarden/common/abstractions/state.service";
|
||||
import { SyncService } from "@bitwarden/common/abstractions/sync/sync.service.abstraction";
|
||||
import { Utils } from "@bitwarden/common/misc/utils";
|
||||
|
||||
@Component({
|
||||
selector: "app-login",
|
||||
templateUrl: "login.component.html",
|
||||
})
|
||||
export class LoginComponent extends BaseLoginComponent {
|
||||
protected alwaysRememberEmail = true;
|
||||
protected skipRememberEmail = true;
|
||||
|
||||
constructor(
|
||||
apiService: ApiService,
|
||||
appIdService: AppIdService,
|
||||
authService: AuthService,
|
||||
router: Router,
|
||||
protected platformUtilsService: PlatformUtilsService,
|
||||
@@ -34,9 +40,13 @@ export class LoginComponent extends BaseLoginComponent {
|
||||
logService: LogService,
|
||||
ngZone: NgZone,
|
||||
formBuilder: FormBuilder,
|
||||
formValidationErrorService: FormValidationErrorsService
|
||||
formValidationErrorService: FormValidationErrorsService,
|
||||
route: ActivatedRoute,
|
||||
loginService: LoginService
|
||||
) {
|
||||
super(
|
||||
apiService,
|
||||
appIdService,
|
||||
authService,
|
||||
router,
|
||||
platformUtilsService,
|
||||
@@ -48,7 +58,9 @@ export class LoginComponent extends BaseLoginComponent {
|
||||
logService,
|
||||
ngZone,
|
||||
formBuilder,
|
||||
formValidationErrorService
|
||||
formValidationErrorService,
|
||||
route,
|
||||
loginService
|
||||
);
|
||||
super.onSuccessfulLogin = async () => {
|
||||
await syncService.fullSync(true);
|
||||
@@ -59,4 +71,45 @@ export class LoginComponent extends BaseLoginComponent {
|
||||
settings() {
|
||||
this.router.navigate(["environment"]);
|
||||
}
|
||||
|
||||
async launchSsoBrowser() {
|
||||
// Generate necessary sso params
|
||||
const passwordOptions: any = {
|
||||
type: "password",
|
||||
length: 64,
|
||||
uppercase: true,
|
||||
lowercase: true,
|
||||
numbers: true,
|
||||
special: false,
|
||||
};
|
||||
|
||||
const state =
|
||||
(await this.passwordGenerationService.generatePassword(passwordOptions)) +
|
||||
":clientId=browser";
|
||||
const codeVerifier = await this.passwordGenerationService.generatePassword(passwordOptions);
|
||||
const codeVerifierHash = await this.cryptoFunctionService.hash(codeVerifier, "sha256");
|
||||
const codeChallenge = Utils.fromBufferToUrlB64(codeVerifierHash);
|
||||
|
||||
await this.stateService.setSsoCodeVerifier(codeVerifier);
|
||||
await this.stateService.setSsoState(state);
|
||||
|
||||
let url = this.environmentService.getWebVaultUrl();
|
||||
if (url == null) {
|
||||
url = "https://vault.bitwarden.com";
|
||||
}
|
||||
|
||||
const redirectUri = url + "/sso-connector.html";
|
||||
|
||||
// Launch browser
|
||||
this.platformUtilsService.launchUri(
|
||||
url +
|
||||
"/#/sso?clientId=browser" +
|
||||
"&redirectUri=" +
|
||||
encodeURIComponent(redirectUri) +
|
||||
"&state=" +
|
||||
state +
|
||||
"&codeChallenge=" +
|
||||
codeChallenge
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import { BroadcasterService } from "@bitwarden/common/abstractions/broadcaster.s
|
||||
import { EnvironmentService } from "@bitwarden/common/abstractions/environment.service";
|
||||
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/abstractions/log.service";
|
||||
import { LoginService } from "@bitwarden/common/abstractions/login.service";
|
||||
import { MessagingService } from "@bitwarden/common/abstractions/messaging.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
|
||||
import { StateService } from "@bitwarden/common/abstractions/state.service";
|
||||
@@ -44,7 +45,8 @@ export class TwoFactorComponent extends BaseTwoFactorComponent {
|
||||
private messagingService: MessagingService,
|
||||
logService: LogService,
|
||||
twoFactorService: TwoFactorService,
|
||||
appIdService: AppIdService
|
||||
appIdService: AppIdService,
|
||||
loginService: LoginService
|
||||
) {
|
||||
super(
|
||||
authService,
|
||||
@@ -58,9 +60,11 @@ export class TwoFactorComponent extends BaseTwoFactorComponent {
|
||||
route,
|
||||
logService,
|
||||
twoFactorService,
|
||||
appIdService
|
||||
appIdService,
|
||||
loginService
|
||||
);
|
||||
super.onSuccessfulLogin = () => {
|
||||
this.loginService.clearValues();
|
||||
return syncService.fullSync(true);
|
||||
};
|
||||
super.successRoute = "/tabs/vault";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<app-callout type="warning" *ngIf="showWarning">
|
||||
<app-callout class="app-private-mode-warning" type="warning" *ngIf="showWarning">
|
||||
{{ "privateModeWarning" | i18n }}
|
||||
<a href="https://bitwarden.com/help/article/private-mode/" target="_blank" rel="noopener">{{
|
||||
"learnMore" | i18n
|
||||
|
||||
@@ -174,6 +174,11 @@ header {
|
||||
|
||||
.right {
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
app-avatar {
|
||||
max-height: 30px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.center {
|
||||
@@ -183,6 +188,10 @@ header {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.login-center {
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
app-pop-out > button,
|
||||
div > button,
|
||||
div > a {
|
||||
|
||||
@@ -83,6 +83,11 @@
|
||||
margin: 5px 10px;
|
||||
font-size: $font-size-small;
|
||||
|
||||
button.btn {
|
||||
font-size: $font-size-small;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
@include themify($themes) {
|
||||
color: themed("mutedColor");
|
||||
}
|
||||
|
||||
@@ -440,3 +440,7 @@ app-vault-view .box-footer {
|
||||
html.force_redraw {
|
||||
animation: redraw 1s linear infinite;
|
||||
}
|
||||
|
||||
.rounded-circle {
|
||||
border-radius: 50% !important;
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ app-home {
|
||||
}
|
||||
}
|
||||
|
||||
app-private-mode-warning {
|
||||
.app-private-mode-warning {
|
||||
display: block;
|
||||
padding-top: 1rem;
|
||||
}
|
||||
@@ -115,3 +115,11 @@ body.body-full {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.createAccountLink {
|
||||
padding-top: 30px;
|
||||
}
|
||||
|
||||
.login-buttons > button {
|
||||
margin: 15px 0 15px 0;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import { FolderService } from "@bitwarden/common/abstractions/folder/folder.serv
|
||||
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
|
||||
import { KeyConnectorService } from "@bitwarden/common/abstractions/keyConnector.service";
|
||||
import { LogService as LogServiceAbstraction } from "@bitwarden/common/abstractions/log.service";
|
||||
import { LoginService as LoginServiceAbstraction } from "@bitwarden/common/abstractions/login.service";
|
||||
import { MessagingService } from "@bitwarden/common/abstractions/messaging.service";
|
||||
import { NotificationsService } from "@bitwarden/common/abstractions/notifications.service";
|
||||
import { OrganizationService } from "@bitwarden/common/abstractions/organization/organization.service.abstraction";
|
||||
@@ -48,6 +49,7 @@ import { VaultTimeoutService } from "@bitwarden/common/abstractions/vaultTimeout
|
||||
import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeoutSettings.service";
|
||||
import { AuthService } from "@bitwarden/common/services/auth.service";
|
||||
import { ConsoleLogService } from "@bitwarden/common/services/consoleLog.service";
|
||||
import { LoginService } from "@bitwarden/common/services/login.service";
|
||||
import { SearchService } from "@bitwarden/common/services/search.service";
|
||||
|
||||
import MainBackground from "../../background/main.background";
|
||||
@@ -309,6 +311,10 @@ function getBgService<T>(service: keyof MainBackground) {
|
||||
provide: FileDownloadService,
|
||||
useClass: BrowserFileDownloadService,
|
||||
},
|
||||
{
|
||||
provide: LoginServiceAbstraction,
|
||||
useClass: LoginService,
|
||||
},
|
||||
{
|
||||
provide: AbstractThemingService,
|
||||
useFactory: () => {
|
||||
|
||||
Reference in New Issue
Block a user