mirror of
https://github.com/bitwarden/browser
synced 2026-02-08 04:33:38 +00:00
key connector service unit tests
This commit is contained in:
@@ -1,9 +1,8 @@
|
||||
import { mock } from "jest-mock-extended";
|
||||
import { firstValueFrom, of } from "rxjs";
|
||||
import { firstValueFrom, of, timeout, TimeoutError } from "rxjs";
|
||||
|
||||
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||
import { OrganizationUserType } from "@bitwarden/common/admin-console/enums";
|
||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||
import { KeyService } from "@bitwarden/key-management";
|
||||
|
||||
import { FakeAccountService, FakeStateProvider, mockAccountServiceWith } from "../../../../spec";
|
||||
@@ -22,11 +21,7 @@ import { MasterKey } from "../../../types/key";
|
||||
import { FakeMasterPasswordService } from "../../master-password/services/fake-master-password.service";
|
||||
import { KeyConnectorUserKeyRequest } from "../models/key-connector-user-key.request";
|
||||
|
||||
import {
|
||||
USES_KEY_CONNECTOR,
|
||||
CONVERT_ACCOUNT_TO_KEY_CONNECTOR,
|
||||
KeyConnectorService,
|
||||
} from "./key-connector.service";
|
||||
import { USES_KEY_CONNECTOR, KeyConnectorService } from "./key-connector.service";
|
||||
|
||||
describe("KeyConnectorService", () => {
|
||||
let keyConnectorService: KeyConnectorService;
|
||||
@@ -37,7 +32,6 @@ describe("KeyConnectorService", () => {
|
||||
const logService = mock<LogService>();
|
||||
const organizationService = mock<OrganizationService>();
|
||||
const keyGenerationService = mock<KeyGenerationService>();
|
||||
const messagingService = mock<MessagingService>();
|
||||
|
||||
let stateProvider: FakeStateProvider;
|
||||
|
||||
@@ -69,7 +63,6 @@ describe("KeyConnectorService", () => {
|
||||
keyGenerationService,
|
||||
async () => {},
|
||||
stateProvider,
|
||||
messagingService,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -233,108 +226,6 @@ describe("KeyConnectorService", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("setConvertAccountRequired", () => {
|
||||
it("should update the convertAccountToKeyConnectorState with the provided value", async () => {
|
||||
const state = stateProvider.activeUser.getFake(CONVERT_ACCOUNT_TO_KEY_CONNECTOR);
|
||||
state.nextState(false);
|
||||
|
||||
const newValue = true;
|
||||
|
||||
await keyConnectorService.setConvertAccountRequired(newValue, mockUserId);
|
||||
|
||||
expect(await firstValueFrom(state.state$)).toBe(newValue);
|
||||
});
|
||||
|
||||
it("should remove the convertAccountToKeyConnectorState", async () => {
|
||||
const state = stateProvider.activeUser.getFake(CONVERT_ACCOUNT_TO_KEY_CONNECTOR);
|
||||
state.nextState(false);
|
||||
|
||||
const newValue: boolean | null = null;
|
||||
|
||||
await keyConnectorService.setConvertAccountRequired(newValue, mockUserId);
|
||||
|
||||
expect(await firstValueFrom(state.state$)).toBe(newValue);
|
||||
});
|
||||
});
|
||||
|
||||
describe("userNeedsMigration", () => {
|
||||
it("should return true if the user needs migration", async () => {
|
||||
// token
|
||||
tokenService.getIsExternal.mockResolvedValue(true);
|
||||
|
||||
// create organization object
|
||||
const data = organizationData(
|
||||
true,
|
||||
true,
|
||||
"https://key-connector-url.com",
|
||||
OrganizationUserType.User,
|
||||
false,
|
||||
);
|
||||
|
||||
// uses KeyConnector
|
||||
const state = stateProvider.singleUser.getFake(mockUserId, USES_KEY_CONNECTOR);
|
||||
state.nextState(false);
|
||||
|
||||
const result = await keyConnectorService.userNeedsMigration(mockUserId, [data]);
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it("should return false when not logged in with sso", async () => {
|
||||
tokenService.getIsExternal.mockResolvedValue(false);
|
||||
const data = organizationData(
|
||||
true,
|
||||
true,
|
||||
"https://key-connector-url.com",
|
||||
OrganizationUserType.User,
|
||||
false,
|
||||
);
|
||||
|
||||
const state = stateProvider.singleUser.getFake(mockUserId, USES_KEY_CONNECTOR);
|
||||
state.nextState(false);
|
||||
|
||||
const result = await keyConnectorService.userNeedsMigration(mockUserId, [data]);
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it("should return false when key connector not enabled in organization", async () => {
|
||||
tokenService.getIsExternal.mockResolvedValue(true);
|
||||
const data = organizationData(
|
||||
true,
|
||||
false,
|
||||
"https://key-connector-url.com",
|
||||
OrganizationUserType.User,
|
||||
false,
|
||||
);
|
||||
|
||||
const state = stateProvider.singleUser.getFake(mockUserId, USES_KEY_CONNECTOR);
|
||||
state.nextState(false);
|
||||
|
||||
const result = await keyConnectorService.userNeedsMigration(mockUserId, [data]);
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it("should return false when user does not need key connector", async () => {
|
||||
tokenService.getIsExternal.mockResolvedValue(true);
|
||||
const data = organizationData(
|
||||
true,
|
||||
true,
|
||||
"https://key-connector-url.com",
|
||||
OrganizationUserType.User,
|
||||
false,
|
||||
);
|
||||
|
||||
const state = stateProvider.singleUser.getFake(mockUserId, USES_KEY_CONNECTOR);
|
||||
state.nextState(true);
|
||||
|
||||
const result = await keyConnectorService.userNeedsMigration(mockUserId, [data]);
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("setMasterKeyFromUrl", () => {
|
||||
it("should set the master key from the provided URL", async () => {
|
||||
// Arrange
|
||||
@@ -436,6 +327,136 @@ describe("KeyConnectorService", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("convertAccountRequired$", () => {
|
||||
beforeEach(async () => {
|
||||
const organization = organizationData(
|
||||
true,
|
||||
true,
|
||||
"https://key-connector-url.com",
|
||||
OrganizationUserType.User,
|
||||
false,
|
||||
);
|
||||
organizationService.organizations$.mockReturnValue(of([organization]));
|
||||
await stateProvider.getUser(mockUserId, USES_KEY_CONNECTOR).update(() => false);
|
||||
tokenService.getIsExternal.mockResolvedValue(true);
|
||||
tokenService.hasAccessToken$.mockReturnValue(of(true));
|
||||
});
|
||||
|
||||
it("should return true when user logged in with sso, belong to organization using key connector and user does not use key connector", async () => {
|
||||
await expect(
|
||||
firstValueFrom(keyConnectorService.convertAccountRequired$.pipe(timeout(100))),
|
||||
).resolves.toEqual(true);
|
||||
});
|
||||
|
||||
it("should return false when user logged in with password", async () => {
|
||||
tokenService.getIsExternal.mockResolvedValue(false);
|
||||
|
||||
await expect(
|
||||
firstValueFrom(keyConnectorService.convertAccountRequired$.pipe(timeout(100))),
|
||||
).resolves.toEqual(false);
|
||||
});
|
||||
|
||||
it("should return false when organization's key connector disabled", async () => {
|
||||
const organization = organizationData(
|
||||
true,
|
||||
false,
|
||||
"https://key-connector-url.com",
|
||||
OrganizationUserType.User,
|
||||
false,
|
||||
);
|
||||
organizationService.organizations$.mockReturnValue(of([organization]));
|
||||
|
||||
await expect(
|
||||
firstValueFrom(keyConnectorService.convertAccountRequired$.pipe(timeout(100))),
|
||||
).resolves.toEqual(false);
|
||||
});
|
||||
|
||||
it("should return false when user is admin of the organization", async () => {
|
||||
const organization = organizationData(
|
||||
true,
|
||||
true,
|
||||
"https://key-connector-url.com",
|
||||
OrganizationUserType.Admin,
|
||||
false,
|
||||
);
|
||||
organizationService.organizations$.mockReturnValue(of([organization]));
|
||||
|
||||
await expect(
|
||||
firstValueFrom(keyConnectorService.convertAccountRequired$.pipe(timeout(100))),
|
||||
).resolves.toEqual(false);
|
||||
});
|
||||
|
||||
it("should return false when user is owner of the organization", async () => {
|
||||
const organization = organizationData(
|
||||
true,
|
||||
true,
|
||||
"https://key-connector-url.com",
|
||||
OrganizationUserType.Owner,
|
||||
false,
|
||||
);
|
||||
organizationService.organizations$.mockReturnValue(of([organization]));
|
||||
|
||||
await expect(
|
||||
firstValueFrom(keyConnectorService.convertAccountRequired$.pipe(timeout(100))),
|
||||
).resolves.toEqual(false);
|
||||
});
|
||||
|
||||
it("should return false when user is provider user of the organization", async () => {
|
||||
const organization = organizationData(
|
||||
true,
|
||||
true,
|
||||
"https://key-connector-url.com",
|
||||
OrganizationUserType.User,
|
||||
true,
|
||||
);
|
||||
organizationService.organizations$.mockReturnValue(of([organization]));
|
||||
|
||||
await expect(
|
||||
firstValueFrom(keyConnectorService.convertAccountRequired$.pipe(timeout(100))),
|
||||
).resolves.toEqual(false);
|
||||
});
|
||||
|
||||
it("should return false when user already uses key connector", async () => {
|
||||
await stateProvider.getUser(mockUserId, USES_KEY_CONNECTOR).update(() => true);
|
||||
|
||||
await expect(
|
||||
firstValueFrom(keyConnectorService.convertAccountRequired$.pipe(timeout(100))),
|
||||
).resolves.toEqual(false);
|
||||
});
|
||||
|
||||
it("should not return any value when user not logged in", async () => {
|
||||
await accountService.switchAccount(null as unknown as UserId);
|
||||
|
||||
await expect(
|
||||
firstValueFrom(keyConnectorService.convertAccountRequired$.pipe(timeout(100))),
|
||||
).rejects.toBeInstanceOf(TimeoutError);
|
||||
});
|
||||
|
||||
it("should not return any value when organization state is empty", async () => {
|
||||
organizationService.organizations$.mockReturnValue(of(null as unknown as Organization[]));
|
||||
|
||||
await expect(
|
||||
firstValueFrom(keyConnectorService.convertAccountRequired$.pipe(timeout(100))),
|
||||
).rejects.toBeInstanceOf(TimeoutError);
|
||||
});
|
||||
|
||||
it("should not return any value when user is not using key connector", async () => {
|
||||
await stateProvider.getUser(mockUserId, USES_KEY_CONNECTOR).update(() => null);
|
||||
|
||||
await expect(
|
||||
firstValueFrom(keyConnectorService.convertAccountRequired$.pipe(timeout(100))),
|
||||
).rejects.toBeInstanceOf(TimeoutError);
|
||||
});
|
||||
|
||||
it("should not return any value when user does not have access token", async () => {
|
||||
tokenService.hasAccessToken$.mockReturnValue(of(false));
|
||||
|
||||
await expect(
|
||||
firstValueFrom(keyConnectorService.convertAccountRequired$.pipe(timeout(100))),
|
||||
).rejects.toBeInstanceOf(TimeoutError);
|
||||
});
|
||||
});
|
||||
|
||||
function organizationData(
|
||||
usesKeyConnector: boolean,
|
||||
keyConnectorEnabled: boolean,
|
||||
|
||||
Reference in New Issue
Block a user