mirror of
https://github.com/bitwarden/browser
synced 2025-12-13 23:03:32 +00:00
[PM-5255] Create login strategy service (#7750)
* refactor login strategies into own service * create login service factory * replaces instances of authService with loginStrategyService * replace more instances of authService * move logout back to auth service * add browser dependencies * fix desktop dependencies * fix cli dependencies * fix lint and test files * fix anonymous hub deps * fix webauthn-login service deps * add loginstrategyservice to bg * move login strategy service and models to auth folder * revert changes to tsconfig * use alias for imports * fix path --------- Co-authored-by: rr-bw <102181210+rr-bw@users.noreply.github.com>
This commit is contained in:
@@ -4,8 +4,8 @@ import { ActivatedRoute, Router } from "@angular/router";
|
||||
import { MockProxy, mock } from "jest-mock-extended";
|
||||
import { Observable, of } from "rxjs";
|
||||
|
||||
import { LoginStrategyServiceAbstraction } from "@bitwarden/auth/common";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
|
||||
import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type";
|
||||
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
|
||||
import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason";
|
||||
@@ -46,7 +46,7 @@ describe("SsoComponent", () => {
|
||||
let fixture: ComponentFixture<TestSsoComponent>;
|
||||
|
||||
// Mock Services
|
||||
let mockAuthService: MockProxy<AuthService>;
|
||||
let mockLoginStrategyService: MockProxy<LoginStrategyServiceAbstraction>;
|
||||
let mockRouter: MockProxy<Router>;
|
||||
let mockI18nService: MockProxy<I18nService>;
|
||||
|
||||
@@ -88,7 +88,7 @@ describe("SsoComponent", () => {
|
||||
|
||||
beforeEach(() => {
|
||||
// Mock Services
|
||||
mockAuthService = mock<AuthService>();
|
||||
mockLoginStrategyService = mock<LoginStrategyServiceAbstraction>();
|
||||
mockRouter = mock<Router>();
|
||||
mockI18nService = mock<I18nService>();
|
||||
|
||||
@@ -108,7 +108,7 @@ describe("SsoComponent", () => {
|
||||
mockLogService = mock<LogService>();
|
||||
mockConfigService = mock<ConfigServiceAbstraction>();
|
||||
|
||||
// Mock authService.logIn params
|
||||
// Mock loginStrategyService.logIn params
|
||||
code = "code";
|
||||
codeVerifier = "codeVerifier";
|
||||
orgIdFromState = "orgIdFromState";
|
||||
@@ -167,7 +167,7 @@ describe("SsoComponent", () => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [TestSsoComponent],
|
||||
providers: [
|
||||
{ provide: AuthService, useValue: mockAuthService },
|
||||
{ provide: LoginStrategyServiceAbstraction, useValue: mockLoginStrategyService },
|
||||
{ provide: Router, useValue: mockRouter },
|
||||
{ provide: I18nService, useValue: mockI18nService },
|
||||
{ provide: ActivatedRoute, useValue: mockActivatedRoute },
|
||||
@@ -230,12 +230,12 @@ describe("SsoComponent", () => {
|
||||
mockAcctDecryptionOpts.withMasterPassword,
|
||||
);
|
||||
|
||||
mockAuthService.logIn.mockResolvedValue(authResult);
|
||||
mockLoginStrategyService.logIn.mockResolvedValue(authResult);
|
||||
});
|
||||
|
||||
it("calls authService.logIn and navigates to the component's defined 2FA route when the auth result requires 2FA and onSuccessfulLoginTwoFactorNavigate is not defined", async () => {
|
||||
await _component.logIn(code, codeVerifier, orgIdFromState);
|
||||
expect(mockAuthService.logIn).toHaveBeenCalledTimes(1);
|
||||
expect(mockLoginStrategyService.logIn).toHaveBeenCalledTimes(1);
|
||||
|
||||
expect(mockOnSuccessfulLoginTwoFactorNavigate).not.toHaveBeenCalled();
|
||||
|
||||
@@ -256,7 +256,7 @@ describe("SsoComponent", () => {
|
||||
|
||||
await _component.logIn(code, codeVerifier, orgIdFromState);
|
||||
|
||||
expect(mockAuthService.logIn).toHaveBeenCalledTimes(1);
|
||||
expect(mockLoginStrategyService.logIn).toHaveBeenCalledTimes(1);
|
||||
expect(mockOnSuccessfulLoginTwoFactorNavigate).toHaveBeenCalledTimes(1);
|
||||
expect(mockRouter.navigate).not.toHaveBeenCalled();
|
||||
expect(mockLogService.error).not.toHaveBeenCalled();
|
||||
@@ -267,7 +267,7 @@ describe("SsoComponent", () => {
|
||||
const testChangePasswordOnSuccessfulLogin = () => {
|
||||
it("navigates to the component's defined change password route when onSuccessfulLoginChangePasswordNavigate callback is undefined", async () => {
|
||||
await _component.logIn(code, codeVerifier, orgIdFromState);
|
||||
expect(mockAuthService.logIn).toHaveBeenCalledTimes(1);
|
||||
expect(mockLoginStrategyService.logIn).toHaveBeenCalledTimes(1);
|
||||
|
||||
expect(mockOnSuccessfulLoginChangePasswordNavigate).not.toHaveBeenCalled();
|
||||
|
||||
@@ -290,7 +290,7 @@ describe("SsoComponent", () => {
|
||||
|
||||
await _component.logIn(code, codeVerifier, orgIdFromState);
|
||||
|
||||
expect(mockAuthService.logIn).toHaveBeenCalledTimes(1);
|
||||
expect(mockLoginStrategyService.logIn).toHaveBeenCalledTimes(1);
|
||||
expect(mockOnSuccessfulLoginChangePasswordNavigate).toHaveBeenCalledTimes(1);
|
||||
expect(mockRouter.navigate).not.toHaveBeenCalled();
|
||||
expect(mockLogService.error).not.toHaveBeenCalled();
|
||||
@@ -301,7 +301,7 @@ describe("SsoComponent", () => {
|
||||
it(`navigates to the component's defined forcePasswordResetRoute when response.forcePasswordReset is ${reasonString}`, async () => {
|
||||
await _component.logIn(code, codeVerifier, orgIdFromState);
|
||||
|
||||
expect(mockAuthService.logIn).toHaveBeenCalledTimes(1);
|
||||
expect(mockLoginStrategyService.logIn).toHaveBeenCalledTimes(1);
|
||||
|
||||
expect(mockOnSuccessfulLoginForceResetNavigate).not.toHaveBeenCalled();
|
||||
|
||||
@@ -322,7 +322,7 @@ describe("SsoComponent", () => {
|
||||
|
||||
await _component.logIn(code, codeVerifier, orgIdFromState);
|
||||
|
||||
expect(mockAuthService.logIn).toHaveBeenCalledTimes(1);
|
||||
expect(mockLoginStrategyService.logIn).toHaveBeenCalledTimes(1);
|
||||
expect(mockOnSuccessfulLoginForceResetNavigate).toHaveBeenCalledTimes(1);
|
||||
expect(mockRouter.navigate).not.toHaveBeenCalled();
|
||||
expect(mockLogService.error).not.toHaveBeenCalled();
|
||||
@@ -342,12 +342,12 @@ describe("SsoComponent", () => {
|
||||
);
|
||||
|
||||
authResult = new AuthResult();
|
||||
mockAuthService.logIn.mockResolvedValue(authResult);
|
||||
mockLoginStrategyService.logIn.mockResolvedValue(authResult);
|
||||
});
|
||||
|
||||
it("navigates to the component's defined trustedDeviceEncRoute route and sets correct flag when onSuccessfulLoginTdeNavigate is undefined ", async () => {
|
||||
await _component.logIn(code, codeVerifier, orgIdFromState);
|
||||
expect(mockAuthService.logIn).toHaveBeenCalledTimes(1);
|
||||
expect(mockLoginStrategyService.logIn).toHaveBeenCalledTimes(1);
|
||||
|
||||
expect(mockStateService.setForceSetPasswordReason).toHaveBeenCalledWith(
|
||||
ForceSetPasswordReason.TdeUserWithoutPasswordHasPasswordResetPermission,
|
||||
@@ -379,7 +379,7 @@ describe("SsoComponent", () => {
|
||||
|
||||
authResult = new AuthResult();
|
||||
authResult.forcePasswordReset = ForceSetPasswordReason.AdminForcePasswordReset;
|
||||
mockAuthService.logIn.mockResolvedValue(authResult);
|
||||
mockLoginStrategyService.logIn.mockResolvedValue(authResult);
|
||||
});
|
||||
|
||||
testForceResetOnSuccessfulLogin(reasonString);
|
||||
@@ -396,13 +396,13 @@ describe("SsoComponent", () => {
|
||||
|
||||
authResult = new AuthResult();
|
||||
authResult.forcePasswordReset = ForceSetPasswordReason.None;
|
||||
mockAuthService.logIn.mockResolvedValue(authResult);
|
||||
mockLoginStrategyService.logIn.mockResolvedValue(authResult);
|
||||
});
|
||||
|
||||
it("navigates to the component's defined trusted device encryption route when login is successful and no callback is defined", async () => {
|
||||
await _component.logIn(code, codeVerifier, orgIdFromState);
|
||||
|
||||
expect(mockAuthService.logIn).toHaveBeenCalledTimes(1);
|
||||
expect(mockLoginStrategyService.logIn).toHaveBeenCalledTimes(1);
|
||||
expect(mockRouter.navigate).toHaveBeenCalledTimes(1);
|
||||
expect(mockRouter.navigate).toHaveBeenCalledWith(
|
||||
[_component.trustedDeviceEncRoute],
|
||||
@@ -417,7 +417,7 @@ describe("SsoComponent", () => {
|
||||
|
||||
await _component.logIn(code, codeVerifier, orgIdFromState);
|
||||
|
||||
expect(mockAuthService.logIn).toHaveBeenCalledTimes(1);
|
||||
expect(mockLoginStrategyService.logIn).toHaveBeenCalledTimes(1);
|
||||
|
||||
expect(mockOnSuccessfulLoginTdeNavigate).toHaveBeenCalledTimes(1);
|
||||
|
||||
@@ -430,7 +430,7 @@ describe("SsoComponent", () => {
|
||||
describe("Set Master Password scenarios", () => {
|
||||
beforeEach(() => {
|
||||
const authResult = new AuthResult();
|
||||
mockAuthService.logIn.mockResolvedValue(authResult);
|
||||
mockLoginStrategyService.logIn.mockResolvedValue(authResult);
|
||||
});
|
||||
|
||||
describe("Given user needs to set a master password", () => {
|
||||
@@ -451,7 +451,7 @@ describe("SsoComponent", () => {
|
||||
);
|
||||
|
||||
await _component.logIn(code, codeVerifier, orgIdFromState);
|
||||
expect(mockAuthService.logIn).toHaveBeenCalledTimes(1);
|
||||
expect(mockLoginStrategyService.logIn).toHaveBeenCalledTimes(1);
|
||||
|
||||
expect(mockOnSuccessfulLoginChangePasswordNavigate).not.toHaveBeenCalled();
|
||||
expect(mockRouter.navigate).not.toHaveBeenCalledWith([_component.changePasswordRoute], {
|
||||
@@ -477,7 +477,7 @@ describe("SsoComponent", () => {
|
||||
|
||||
const authResult = new AuthResult();
|
||||
authResult.forcePasswordReset = forceResetPasswordReason;
|
||||
mockAuthService.logIn.mockResolvedValue(authResult);
|
||||
mockLoginStrategyService.logIn.mockResolvedValue(authResult);
|
||||
});
|
||||
|
||||
testForceResetOnSuccessfulLogin(reasonString);
|
||||
@@ -494,13 +494,13 @@ describe("SsoComponent", () => {
|
||||
mockAcctDecryptionOpts.withMasterPassword,
|
||||
);
|
||||
authResult.forcePasswordReset = ForceSetPasswordReason.None;
|
||||
mockAuthService.logIn.mockResolvedValue(authResult);
|
||||
mockLoginStrategyService.logIn.mockResolvedValue(authResult);
|
||||
});
|
||||
|
||||
it("calls authService.logIn and navigates to the component's defined success route when the login is successful", async () => {
|
||||
await _component.logIn(code, codeVerifier, orgIdFromState);
|
||||
|
||||
expect(mockAuthService.logIn).toHaveBeenCalled();
|
||||
expect(mockLoginStrategyService.logIn).toHaveBeenCalled();
|
||||
|
||||
expect(mockOnSuccessfulLoginNavigate).not.toHaveBeenCalled();
|
||||
expect(mockOnSuccessfulLogin).not.toHaveBeenCalled();
|
||||
@@ -516,7 +516,7 @@ describe("SsoComponent", () => {
|
||||
|
||||
await _component.logIn(code, codeVerifier, orgIdFromState);
|
||||
|
||||
expect(mockAuthService.logIn).toHaveBeenCalled();
|
||||
expect(mockLoginStrategyService.logIn).toHaveBeenCalled();
|
||||
expect(mockOnSuccessfulLogin).toHaveBeenCalledTimes(1);
|
||||
|
||||
expect(mockOnSuccessfulLoginNavigate).not.toHaveBeenCalled();
|
||||
@@ -533,7 +533,7 @@ describe("SsoComponent", () => {
|
||||
|
||||
await _component.logIn(code, codeVerifier, orgIdFromState);
|
||||
|
||||
expect(mockAuthService.logIn).toHaveBeenCalled();
|
||||
expect(mockLoginStrategyService.logIn).toHaveBeenCalled();
|
||||
|
||||
expect(mockOnSuccessfulLoginNavigate).toHaveBeenCalledTimes(1);
|
||||
|
||||
@@ -547,7 +547,7 @@ describe("SsoComponent", () => {
|
||||
it("calls handleLoginError when an error is thrown during logIn", async () => {
|
||||
const errorMessage = "Key Connector error";
|
||||
const error = new Error(errorMessage);
|
||||
mockAuthService.logIn.mockRejectedValue(error);
|
||||
mockLoginStrategyService.logIn.mockRejectedValue(error);
|
||||
|
||||
const handleLoginErrorSpy = jest.spyOn(_component, "handleLoginError");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user