Remove specific client services.
This commit is contained in:
parent
86a10f21b3
commit
a104a9250d
|
@ -1,57 +0,0 @@
|
||||||
import { Injectable, NgZone } from "@angular/core";
|
|
||||||
|
|
||||||
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
|
||||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Functionality for the desktop login component.
|
|
||||||
*/
|
|
||||||
@Injectable({
|
|
||||||
providedIn: "root",
|
|
||||||
})
|
|
||||||
export class DesktopLoginService {
|
|
||||||
private deferFocus: boolean = null;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private broadcasterService: BroadcasterService,
|
|
||||||
private messagingService: MessagingService,
|
|
||||||
private ngZone: NgZone,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets up the window focus handler.
|
|
||||||
*
|
|
||||||
* @param focusInputCallback
|
|
||||||
*/
|
|
||||||
setupWindowFocusHandler(focusInputCallback: () => void): void {
|
|
||||||
const subscriptionId = "LoginComponent";
|
|
||||||
// TODO: refactor to not use deprecated broadcaster service.
|
|
||||||
this.broadcasterService.subscribe(subscriptionId, (message: any) => {
|
|
||||||
this.ngZone.run(() => {
|
|
||||||
if (message.command === "windowIsFocused") {
|
|
||||||
this.handleWindowFocus(message.windowIsFocused, focusInputCallback);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
this.messagingService.send("getWindowIsFocused");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles the window focus event.
|
|
||||||
*
|
|
||||||
* @param windowIsFocused
|
|
||||||
* @param focusInputCallback
|
|
||||||
*/
|
|
||||||
private handleWindowFocus(windowIsFocused: boolean, focusInputCallback: () => void): void {
|
|
||||||
if (this.deferFocus === null) {
|
|
||||||
this.deferFocus = !windowIsFocused;
|
|
||||||
if (!this.deferFocus) {
|
|
||||||
focusInputCallback();
|
|
||||||
}
|
|
||||||
} else if (this.deferFocus && windowIsFocused) {
|
|
||||||
focusInputCallback();
|
|
||||||
this.deferFocus = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,45 +0,0 @@
|
||||||
import { TestBed } from "@angular/core/testing";
|
|
||||||
import { Router } from "@angular/router";
|
|
||||||
|
|
||||||
import { LoginEmailServiceAbstraction } from "@bitwarden/auth/common";
|
|
||||||
|
|
||||||
import { ExtensionLoginService } from "./extension-login.service";
|
|
||||||
|
|
||||||
describe("ExtensionLoginService", () => {
|
|
||||||
let service: ExtensionLoginService;
|
|
||||||
let routerMock: jest.Mocked<Router>;
|
|
||||||
let loginEmailServiceMock: jest.Mocked<LoginEmailServiceAbstraction>;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
routerMock = {
|
|
||||||
navigate: jest.fn(),
|
|
||||||
} as unknown as jest.Mocked<Router>;
|
|
||||||
|
|
||||||
loginEmailServiceMock = {
|
|
||||||
clearValues: jest.fn(),
|
|
||||||
} as unknown as jest.Mocked<LoginEmailServiceAbstraction>;
|
|
||||||
|
|
||||||
TestBed.configureTestingModule({
|
|
||||||
providers: [
|
|
||||||
ExtensionLoginService,
|
|
||||||
{ provide: Router, useValue: routerMock },
|
|
||||||
{ provide: LoginEmailServiceAbstraction, useValue: loginEmailServiceMock },
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
service = TestBed.inject(ExtensionLoginService);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("creates the service", () => {
|
|
||||||
expect(service).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("handleSuccessfulLogin", () => {
|
|
||||||
it("clears login email service values and navigates to vault", async () => {
|
|
||||||
await service.handleSuccessfulLogin();
|
|
||||||
|
|
||||||
expect(loginEmailServiceMock.clearValues).toHaveBeenCalled();
|
|
||||||
expect(routerMock.navigate).toHaveBeenCalledWith(["/tabs/vault"]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,25 +0,0 @@
|
||||||
import { Injectable } from "@angular/core";
|
|
||||||
import { Router } from "@angular/router";
|
|
||||||
|
|
||||||
import { LoginEmailServiceAbstraction } from "@bitwarden/auth/common";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Functionality for the extension login component.
|
|
||||||
*/
|
|
||||||
@Injectable({
|
|
||||||
providedIn: "root",
|
|
||||||
})
|
|
||||||
export class ExtensionLoginService {
|
|
||||||
constructor(
|
|
||||||
private router: Router,
|
|
||||||
private loginEmailService: LoginEmailServiceAbstraction,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles the successful login - clears the login email service values and navigates to the vault.
|
|
||||||
*/
|
|
||||||
async handleSuccessfulLogin(): Promise<void> {
|
|
||||||
this.loginEmailService.clearValues();
|
|
||||||
await this.router.navigate(["/tabs/vault"]);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -42,10 +42,7 @@ import {
|
||||||
import { AnonLayoutWrapperDataService } from "../anon-layout/anon-layout-wrapper-data.service";
|
import { AnonLayoutWrapperDataService } from "../anon-layout/anon-layout-wrapper-data.service";
|
||||||
import { WaveIcon } from "../icons";
|
import { WaveIcon } from "../icons";
|
||||||
|
|
||||||
import { DesktopLoginService } from "./desktop-login.service";
|
|
||||||
import { ExtensionLoginService } from "./extension-login.service";
|
|
||||||
import { LoginComponentService } from "./login-component.service";
|
import { LoginComponentService } from "./login-component.service";
|
||||||
import { WebLoginService } from "./web-login.service";
|
|
||||||
|
|
||||||
const BroadcasterSubscriptionId = "LoginComponent";
|
const BroadcasterSubscriptionId = "LoginComponent";
|
||||||
|
|
||||||
|
@ -139,9 +136,6 @@ export class LoginComponent implements OnInit, OnDestroy {
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private syncService: SyncService,
|
private syncService: SyncService,
|
||||||
private toastService: ToastService,
|
private toastService: ToastService,
|
||||||
private webLoginService: WebLoginService,
|
|
||||||
private desktopLoginService: DesktopLoginService,
|
|
||||||
private extensionLoginService: ExtensionLoginService,
|
|
||||||
) {
|
) {
|
||||||
this.clientType = this.platformUtilsService.getClientType();
|
this.clientType = this.platformUtilsService.getClientType();
|
||||||
this.loginViaAuthRequestSupported = this.loginComponentService.isLoginViaAuthRequestSupported();
|
this.loginViaAuthRequestSupported = this.loginComponentService.isLoginViaAuthRequestSupported();
|
||||||
|
@ -275,7 +269,8 @@ export class LoginComponent implements OnInit, OnDestroy {
|
||||||
await this.goAfterLogIn(authResult.userId);
|
await this.goAfterLogIn(authResult.userId);
|
||||||
// ...on Browser/Desktop
|
// ...on Browser/Desktop
|
||||||
} else if (this.clientType === ClientType.Browser) {
|
} else if (this.clientType === ClientType.Browser) {
|
||||||
await this.extensionLoginService.handleSuccessfulLogin();
|
this.loginEmailService.clearValues();
|
||||||
|
await this.router.navigate(["/tabs/vault"]);
|
||||||
} else {
|
} else {
|
||||||
await this.router.navigate(["vault"]);
|
await this.router.navigate(["vault"]);
|
||||||
this.loginEmailService.clearValues();
|
this.loginEmailService.clearValues();
|
||||||
|
@ -520,21 +515,24 @@ export class LoginComponent implements OnInit, OnDestroy {
|
||||||
}
|
}
|
||||||
|
|
||||||
private async webOnInit(): Promise<void> {
|
private async webOnInit(): Promise<void> {
|
||||||
this.activatedRoute.queryParams
|
this.activatedRoute.queryParams.pipe(first(), takeUntil(this.destroy$)).subscribe((qParams) => {
|
||||||
.pipe(
|
if (qParams.org != null) {
|
||||||
first(),
|
const route = this.router.createUrlTree(["create-organization"], {
|
||||||
switchMap((qParams) => this.webLoginService.handleQueryParams(qParams)),
|
queryParams: { plan: qParams.org },
|
||||||
takeUntil(this.destroy$),
|
});
|
||||||
)
|
this.loginComponentService.setPreviousUrl(route);
|
||||||
.subscribe({
|
}
|
||||||
error: (error: unknown) => {
|
|
||||||
this.toastService.showToast({
|
/* If there is a parameter called 'sponsorshipToken', they are coming
|
||||||
variant: "error",
|
from an email for sponsoring a families organization. Therefore set
|
||||||
title: this.i18nService.t("errorOccurred"),
|
the prevousUrl to /setup/families-for-enterprise?token=<paramValue> */
|
||||||
message: String(error),
|
if (qParams.sponsorshipToken != null) {
|
||||||
});
|
const route = this.router.createUrlTree(["setup/families-for-enterprise"], {
|
||||||
},
|
queryParams: { token: qParams.sponsorshipToken },
|
||||||
});
|
});
|
||||||
|
this.loginComponentService.setPreviousUrl(route);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO-rr-bw: Verify the following
|
* TODO-rr-bw: Verify the following
|
||||||
|
@ -553,6 +551,27 @@ export class LoginComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
private async desktopOnInit(): Promise<void> {
|
private async desktopOnInit(): Promise<void> {
|
||||||
await this.getLoginWithDevice(this.loggedEmail);
|
await this.getLoginWithDevice(this.loggedEmail);
|
||||||
this.desktopLoginService.setupWindowFocusHandler(() => this.focusInput());
|
|
||||||
|
// TODO-rr-bw: refactor to not use deprecated broadcaster service.
|
||||||
|
this.broadcasterService.subscribe(BroadcasterSubscriptionId, async (message: any) => {
|
||||||
|
this.ngZone.run(() => {
|
||||||
|
switch (message.command) {
|
||||||
|
case "windowIsFocused":
|
||||||
|
if (this.deferFocus === null) {
|
||||||
|
this.deferFocus = !message.windowIsFocused;
|
||||||
|
if (!this.deferFocus) {
|
||||||
|
this.focusInput();
|
||||||
|
}
|
||||||
|
} else if (this.deferFocus && message.windowIsFocused) {
|
||||||
|
this.focusInput();
|
||||||
|
this.deferFocus = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
this.messagingService.send("getWindowIsFocused");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,72 +0,0 @@
|
||||||
import { TestBed } from "@angular/core/testing";
|
|
||||||
import { Router } from "@angular/router";
|
|
||||||
|
|
||||||
import { LoginComponentService } from "./login-component.service";
|
|
||||||
import { WebLoginService } from "./web-login.service";
|
|
||||||
|
|
||||||
describe("WebLoginService", () => {
|
|
||||||
let service: WebLoginService;
|
|
||||||
let routerMock: jest.Mocked<Router>;
|
|
||||||
let loginComponentServiceMock: jest.Mocked<LoginComponentService>;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
routerMock = {
|
|
||||||
createUrlTree: jest.fn(),
|
|
||||||
} as unknown as jest.Mocked<Router>;
|
|
||||||
|
|
||||||
loginComponentServiceMock = {
|
|
||||||
setPreviousUrl: jest.fn(),
|
|
||||||
} as unknown as jest.Mocked<LoginComponentService>;
|
|
||||||
|
|
||||||
TestBed.configureTestingModule({
|
|
||||||
providers: [
|
|
||||||
WebLoginService,
|
|
||||||
{ provide: Router, useValue: routerMock },
|
|
||||||
{ provide: LoginComponentService, useValue: loginComponentServiceMock },
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
service = TestBed.inject(WebLoginService);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("creates the service", () => {
|
|
||||||
expect(service).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("handleQueryParams", () => {
|
|
||||||
it("sets previous URL for organization creation when org param is present", async () => {
|
|
||||||
const qParams = { org: "some-org" };
|
|
||||||
const mockUrlTree = {} as any;
|
|
||||||
routerMock.createUrlTree.mockReturnValue(mockUrlTree);
|
|
||||||
|
|
||||||
await service.handleQueryParams(qParams);
|
|
||||||
|
|
||||||
expect(routerMock.createUrlTree).toHaveBeenCalledWith(["create-organization"], {
|
|
||||||
queryParams: { plan: "some-org" },
|
|
||||||
});
|
|
||||||
expect(loginComponentServiceMock.setPreviousUrl).toHaveBeenCalledWith(mockUrlTree);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("sets previous URL for families sponsorship when sponsorshipToken param is present", async () => {
|
|
||||||
const qParams = { sponsorshipToken: "test-token" };
|
|
||||||
const mockUrlTree = {} as any;
|
|
||||||
routerMock.createUrlTree.mockReturnValue(mockUrlTree);
|
|
||||||
|
|
||||||
await service.handleQueryParams(qParams);
|
|
||||||
|
|
||||||
expect(routerMock.createUrlTree).toHaveBeenCalledWith(["setup/families-for-enterprise"], {
|
|
||||||
queryParams: { token: "test-token" },
|
|
||||||
});
|
|
||||||
expect(loginComponentServiceMock.setPreviousUrl).toHaveBeenCalledWith(mockUrlTree);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("does not set previous URL when no relevant params are present", async () => {
|
|
||||||
const qParams = { someOtherParam: "value" };
|
|
||||||
|
|
||||||
await service.handleQueryParams(qParams);
|
|
||||||
|
|
||||||
expect(routerMock.createUrlTree).not.toHaveBeenCalled();
|
|
||||||
expect(loginComponentServiceMock.setPreviousUrl).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,38 +0,0 @@
|
||||||
import { Injectable } from "@angular/core";
|
|
||||||
import { Router } from "@angular/router";
|
|
||||||
|
|
||||||
import { LoginComponentService } from "./login-component.service";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Functionality for the web login component.
|
|
||||||
*/
|
|
||||||
@Injectable({
|
|
||||||
providedIn: "root",
|
|
||||||
})
|
|
||||||
export class WebLoginService {
|
|
||||||
constructor(
|
|
||||||
private router: Router,
|
|
||||||
private loginComponentService: LoginComponentService,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
async handleQueryParams(qParams: any): Promise<void> {
|
|
||||||
if (qParams.org != null) {
|
|
||||||
const route = this.router.createUrlTree(["create-organization"], {
|
|
||||||
queryParams: { plan: qParams.org },
|
|
||||||
});
|
|
||||||
this.loginComponentService.setPreviousUrl(route);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If there is a parameter called 'sponsorshipToken', they are coming
|
|
||||||
* from an email for sponsoring a families organization. Therefore set
|
|
||||||
* the previousUrl to /setup/families-for-enterprise?token=<paramValue>
|
|
||||||
*/
|
|
||||||
if (qParams.sponsorshipToken != null) {
|
|
||||||
const route = this.router.createUrlTree(["setup/families-for-enterprise"], {
|
|
||||||
queryParams: { token: qParams.sponsorshipToken },
|
|
||||||
});
|
|
||||||
this.loginComponentService.setPreviousUrl(route);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue