mirror of
https://github.com/bitwarden/browser
synced 2025-12-20 02:03:39 +00:00
[PM-24677] Slim StateService down so it can be moved to state lib (#16021)
* Slim StateService down so it can be moved to state lib * Fix accidental import changes * Add `switchAccount` assertion * Needs to use mock
This commit is contained in:
@@ -2,6 +2,7 @@ import { mock, MockProxy } from "jest-mock-extended";
|
||||
import { BehaviorSubject, of } from "rxjs";
|
||||
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
|
||||
import {
|
||||
AUTOFILL_CARD_ID,
|
||||
AUTOFILL_ID,
|
||||
@@ -17,7 +18,6 @@ import { AutofillSettingsServiceAbstraction } from "@bitwarden/common/autofill/s
|
||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
||||
import { UserId } from "@bitwarden/common/types/guid";
|
||||
import { CipherType } from "@bitwarden/common/vault/enums";
|
||||
import { Cipher } from "@bitwarden/common/vault/models/domain/cipher";
|
||||
@@ -67,7 +67,7 @@ const createCipher = (data?: {
|
||||
};
|
||||
|
||||
describe("context-menu", () => {
|
||||
let stateService: MockProxy<StateService>;
|
||||
let tokenService: MockProxy<TokenService>;
|
||||
let autofillSettingsService: MockProxy<AutofillSettingsServiceAbstraction>;
|
||||
let i18nService: MockProxy<I18nService>;
|
||||
let logService: MockProxy<LogService>;
|
||||
@@ -85,7 +85,7 @@ describe("context-menu", () => {
|
||||
let sut: MainContextMenuHandler;
|
||||
|
||||
beforeEach(() => {
|
||||
stateService = mock();
|
||||
tokenService = mock();
|
||||
autofillSettingsService = mock();
|
||||
i18nService = mock();
|
||||
logService = mock();
|
||||
@@ -109,7 +109,7 @@ describe("context-menu", () => {
|
||||
|
||||
i18nService.t.mockImplementation((key) => key);
|
||||
sut = new MainContextMenuHandler(
|
||||
stateService,
|
||||
tokenService,
|
||||
autofillSettingsService,
|
||||
i18nService,
|
||||
logService,
|
||||
@@ -276,7 +276,7 @@ describe("context-menu", () => {
|
||||
it("removes menu items that require code injection", async () => {
|
||||
billingAccountProfileStateService.hasPremiumFromAnySource$.mockReturnValue(of(true));
|
||||
autofillSettingsService.enableContextMenu$ = of(true);
|
||||
stateService.getIsAuthenticated.mockResolvedValue(true);
|
||||
tokenService.hasAccessToken$.mockReturnValue(of(true));
|
||||
|
||||
const optionId = "1";
|
||||
await sut.loadOptions("TEST_TITLE", optionId, createCipher());
|
||||
@@ -317,7 +317,7 @@ describe("context-menu", () => {
|
||||
});
|
||||
|
||||
it("Loads context menu items that ask the user to unlock their vault if they are authed", async () => {
|
||||
stateService.getIsAuthenticated.mockResolvedValue(true);
|
||||
tokenService.hasAccessToken$.mockReturnValue(of(true));
|
||||
|
||||
await sut.noAccess();
|
||||
|
||||
@@ -325,7 +325,7 @@ describe("context-menu", () => {
|
||||
});
|
||||
|
||||
it("Loads context menu items that ask the user to login to their vault if they are not authed", async () => {
|
||||
stateService.getIsAuthenticated.mockResolvedValue(false);
|
||||
tokenService.hasAccessToken$.mockReturnValue(of(false));
|
||||
|
||||
await sut.noAccess();
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { firstValueFrom } from "rxjs";
|
||||
import { firstValueFrom, map } from "rxjs";
|
||||
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
|
||||
import {
|
||||
AUTOFILL_CARD_ID,
|
||||
AUTOFILL_ID,
|
||||
@@ -23,7 +24,6 @@ import { AutofillSettingsServiceAbstraction } from "@bitwarden/common/autofill/s
|
||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { CipherType } from "@bitwarden/common/vault/enums/cipher-type";
|
||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||
@@ -152,7 +152,7 @@ export class MainContextMenuHandler {
|
||||
];
|
||||
|
||||
constructor(
|
||||
private stateService: StateService,
|
||||
private tokenService: TokenService,
|
||||
private autofillSettingsService: AutofillSettingsServiceAbstraction,
|
||||
private i18nService: I18nService,
|
||||
private logService: LogService,
|
||||
@@ -343,7 +343,11 @@ export class MainContextMenuHandler {
|
||||
|
||||
async noAccess() {
|
||||
if (await this.init()) {
|
||||
const authed = await this.stateService.getIsAuthenticated();
|
||||
const userId = await firstValueFrom(
|
||||
this.accountService.activeAccount$.pipe(map((a) => a?.id)),
|
||||
);
|
||||
const authed =
|
||||
userId != null && (await firstValueFrom(this.tokenService.hasAccessToken$(userId)));
|
||||
this.loadOptions(
|
||||
this.i18nService.t(authed ? "unlockVaultMenu" : "loginToVaultMenu"),
|
||||
NOOP_COMMAND_SUFFIX,
|
||||
|
||||
@@ -111,14 +111,11 @@ import {
|
||||
ObservableStorageService,
|
||||
} from "@bitwarden/common/platform/abstractions/storage.service";
|
||||
import { SystemService as SystemServiceAbstraction } from "@bitwarden/common/platform/abstractions/system.service";
|
||||
import { StateFactory } from "@bitwarden/common/platform/factories/state-factory";
|
||||
import { IpcService } from "@bitwarden/common/platform/ipc";
|
||||
import { Message, MessageListener, MessageSender } from "@bitwarden/common/platform/messaging";
|
||||
// eslint-disable-next-line no-restricted-imports -- Used for dependency creation
|
||||
import { SubjectMessageSender } from "@bitwarden/common/platform/messaging/internal";
|
||||
import { Lazy } from "@bitwarden/common/platform/misc/lazy";
|
||||
import { Account } from "@bitwarden/common/platform/models/domain/account";
|
||||
import { GlobalState } from "@bitwarden/common/platform/models/domain/global-state";
|
||||
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
|
||||
import { NotificationsService } from "@bitwarden/common/platform/notifications";
|
||||
// eslint-disable-next-line no-restricted-imports -- Needed for service creation
|
||||
@@ -143,11 +140,11 @@ import { MigrationRunner } from "@bitwarden/common/platform/services/migration-r
|
||||
import { DefaultSdkClientFactory } from "@bitwarden/common/platform/services/sdk/default-sdk-client-factory";
|
||||
import { DefaultSdkService } from "@bitwarden/common/platform/services/sdk/default-sdk.service";
|
||||
import { NoopSdkClientFactory } from "@bitwarden/common/platform/services/sdk/noop-sdk-client-factory";
|
||||
import { StateService } from "@bitwarden/common/platform/services/state.service";
|
||||
import { SystemService } from "@bitwarden/common/platform/services/system.service";
|
||||
import { UserAutoUnlockKeyService } from "@bitwarden/common/platform/services/user-auto-unlock-key.service";
|
||||
import {
|
||||
ActiveUserStateProvider,
|
||||
DefaultStateService,
|
||||
DerivedStateProvider,
|
||||
GlobalStateProvider,
|
||||
SingleUserStateProvider,
|
||||
@@ -387,6 +384,7 @@ export default class MainBackground {
|
||||
activeUserStateProvider: ActiveUserStateProvider;
|
||||
derivedStateProvider: DerivedStateProvider;
|
||||
stateProvider: StateProvider;
|
||||
migrationRunner: MigrationRunner;
|
||||
taskSchedulerService: BrowserTaskSchedulerService;
|
||||
fido2Background: Fido2BackgroundAbstraction;
|
||||
individualVaultExportService: IndividualVaultExportServiceAbstraction;
|
||||
@@ -592,8 +590,9 @@ export default class MainBackground {
|
||||
this.globalStateProvider,
|
||||
this.singleUserStateProvider,
|
||||
);
|
||||
const activeUserAccessor = new DefaultActiveUserAccessor(this.accountService);
|
||||
this.activeUserStateProvider = new DefaultActiveUserStateProvider(
|
||||
new DefaultActiveUserAccessor(this.accountService),
|
||||
activeUserAccessor,
|
||||
this.singleUserStateProvider,
|
||||
);
|
||||
this.derivedStateProvider = new InlineDerivedStateProvider();
|
||||
@@ -639,23 +638,17 @@ export default class MainBackground {
|
||||
this.taskSchedulerService,
|
||||
);
|
||||
|
||||
const migrationRunner = new MigrationRunner(
|
||||
this.migrationRunner = new MigrationRunner(
|
||||
this.storageService,
|
||||
this.logService,
|
||||
new MigrationBuilderService(),
|
||||
ClientType.Browser,
|
||||
);
|
||||
|
||||
this.stateService = new StateService(
|
||||
this.stateService = new DefaultStateService(
|
||||
this.storageService,
|
||||
this.secureStorageService,
|
||||
this.memoryStorageService,
|
||||
this.logService,
|
||||
new StateFactory(GlobalState, Account),
|
||||
this.accountService,
|
||||
this.environmentService,
|
||||
this.tokenService,
|
||||
migrationRunner,
|
||||
activeUserAccessor,
|
||||
);
|
||||
|
||||
this.masterPasswordService = new MasterPasswordService(
|
||||
@@ -887,7 +880,6 @@ export default class MainBackground {
|
||||
this.apiService,
|
||||
this.i18nService,
|
||||
this.searchService,
|
||||
this.stateService,
|
||||
this.autofillSettingsService,
|
||||
this.encryptService,
|
||||
this.cipherFileUploadService,
|
||||
@@ -946,6 +938,7 @@ export default class MainBackground {
|
||||
this.messagingService,
|
||||
this.searchService,
|
||||
this.stateService,
|
||||
this.tokenService,
|
||||
this.authService,
|
||||
this.vaultTimeoutSettingsService,
|
||||
this.stateEventRunnerService,
|
||||
@@ -989,7 +982,6 @@ export default class MainBackground {
|
||||
this.sendService,
|
||||
this.logService,
|
||||
this.keyConnectorService,
|
||||
this.stateService,
|
||||
this.providerService,
|
||||
this.folderApiService,
|
||||
this.organizationService,
|
||||
@@ -1320,7 +1312,7 @@ export default class MainBackground {
|
||||
);
|
||||
|
||||
this.mainContextMenuHandler = new MainContextMenuHandler(
|
||||
this.stateService,
|
||||
this.tokenService,
|
||||
this.autofillSettingsService,
|
||||
this.i18nService,
|
||||
this.logService,
|
||||
@@ -1387,7 +1379,7 @@ export default class MainBackground {
|
||||
|
||||
await this.sdkLoadService.loadAndInit();
|
||||
// Only the "true" background should run migrations
|
||||
await this.stateService.init({ runMigrations: true });
|
||||
await this.migrationRunner.run();
|
||||
|
||||
// This is here instead of in in the InitService b/c we don't plan for
|
||||
// side effects to run in the Browser InitService.
|
||||
@@ -1607,6 +1599,7 @@ export default class MainBackground {
|
||||
const needStorageReseed = await this.needsStorageReseed(userBeingLoggedOut);
|
||||
|
||||
await this.stateService.clean({ userId: userBeingLoggedOut });
|
||||
await this.tokenService.clearAccessToken(userBeingLoggedOut);
|
||||
await this.accountService.clean(userBeingLoggedOut);
|
||||
|
||||
await this.stateEventRunnerService.handleEvent("logout", userBeingLoggedOut);
|
||||
|
||||
@@ -4,8 +4,8 @@ import { Subject } from "rxjs";
|
||||
import { CollectionService } from "@bitwarden/admin-console/common";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
|
||||
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
||||
import { MessageListener, MessageSender } from "@bitwarden/common/platform/messaging";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { SyncOptions } from "@bitwarden/common/platform/sync/sync.service";
|
||||
@@ -22,7 +22,7 @@ import { FullSyncFinishedMessage } from "./sync-service.listener";
|
||||
|
||||
describe("ForegroundSyncService", () => {
|
||||
const userId = Utils.newGuid() as UserId;
|
||||
const stateService = mock<StateService>();
|
||||
const tokenService = mock<TokenService>();
|
||||
const folderService = mock<InternalFolderService>();
|
||||
const folderApiService = mock<FolderApiServiceAbstraction>();
|
||||
const messageSender = mock<MessageSender>();
|
||||
@@ -38,7 +38,7 @@ describe("ForegroundSyncService", () => {
|
||||
const stateProvider = new FakeStateProvider(accountService);
|
||||
|
||||
const sut = new ForegroundSyncService(
|
||||
stateService,
|
||||
tokenService,
|
||||
folderService,
|
||||
folderApiService,
|
||||
messageSender,
|
||||
|
||||
@@ -4,8 +4,8 @@ import { CollectionService } from "@bitwarden/admin-console/common";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
|
||||
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
||||
import {
|
||||
CommandDefinition,
|
||||
MessageListener,
|
||||
@@ -31,7 +31,7 @@ export const DO_FULL_SYNC = new CommandDefinition<FullSyncMessage>("doFullSync")
|
||||
|
||||
export class ForegroundSyncService extends CoreSyncService {
|
||||
constructor(
|
||||
stateService: StateService,
|
||||
tokenService: TokenService,
|
||||
folderService: InternalFolderService,
|
||||
folderApiService: FolderApiServiceAbstraction,
|
||||
messageSender: MessageSender,
|
||||
@@ -47,7 +47,7 @@ export class ForegroundSyncService extends CoreSyncService {
|
||||
stateProvider: StateProvider,
|
||||
) {
|
||||
super(
|
||||
stateService,
|
||||
tokenService,
|
||||
folderService,
|
||||
folderApiService,
|
||||
messageSender,
|
||||
|
||||
@@ -28,13 +28,13 @@ import { DocumentLangSetter } from "@bitwarden/angular/platform/i18n";
|
||||
import { LogoutReason, UserDecryptionOptionsServiceAbstraction } from "@bitwarden/auth/common";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
|
||||
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
|
||||
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
||||
import { AnimationControlService } from "@bitwarden/common/platform/abstractions/animation-control.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { SdkService } from "@bitwarden/common/platform/abstractions/sdk/sdk.service";
|
||||
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
||||
import { MessageListener } from "@bitwarden/common/platform/messaging";
|
||||
import { UserId } from "@bitwarden/common/types/guid";
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
@@ -102,7 +102,7 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||
private authService: AuthService,
|
||||
private i18nService: I18nService,
|
||||
private router: Router,
|
||||
private stateService: StateService,
|
||||
private readonly tokenService: TokenService,
|
||||
private vaultBrowserStateService: VaultBrowserStateService,
|
||||
private cipherService: CipherService,
|
||||
private changeDetectorRef: ChangeDetectorRef,
|
||||
@@ -321,7 +321,7 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
private async clearComponentStates() {
|
||||
if (!(await this.stateService.getIsAuthenticated())) {
|
||||
if (!(await firstValueFrom(this.tokenService.hasAccessToken$(this.activeUserId)))) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import { LogService as LogServiceAbstraction } from "@bitwarden/common/platform/
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { SdkLoadService } from "@bitwarden/common/platform/abstractions/sdk/sdk-load.service";
|
||||
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
||||
import { MigrationRunner } from "@bitwarden/common/platform/services/migration-runner";
|
||||
|
||||
import { BrowserApi } from "../../platform/browser/browser-api";
|
||||
import BrowserPopupUtils from "../../platform/browser/browser-popup-utils";
|
||||
@@ -27,13 +28,14 @@ export class InitService {
|
||||
private themingService: AbstractThemingService,
|
||||
private sdkLoadService: SdkLoadService,
|
||||
private viewCacheService: PopupViewCacheService,
|
||||
private readonly migrationRunner: MigrationRunner,
|
||||
@Inject(DOCUMENT) private document: Document,
|
||||
) {}
|
||||
|
||||
init() {
|
||||
return async () => {
|
||||
await this.sdkLoadService.loadAndInit();
|
||||
await this.stateService.init({ runMigrations: false }); // Browser background is responsible for migrations
|
||||
await this.migrationRunner.waitForCompletion(); // Browser background is responsible for migrations
|
||||
await this.i18nService.init();
|
||||
this.twoFactorService.init();
|
||||
await this.viewCacheService.init();
|
||||
|
||||
@@ -47,6 +47,7 @@ import {
|
||||
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
|
||||
import { MasterPasswordApiService } from "@bitwarden/common/auth/abstractions/master-password-api.service.abstraction";
|
||||
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
|
||||
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
|
||||
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
||||
import {
|
||||
AutofillSettingsService,
|
||||
@@ -333,7 +334,7 @@ const safeProviders: SafeProvider[] = [
|
||||
provide: SyncService,
|
||||
useClass: ForegroundSyncService,
|
||||
deps: [
|
||||
StateService,
|
||||
TokenService,
|
||||
InternalFolderService,
|
||||
FolderApiServiceAbstraction,
|
||||
MessageSender,
|
||||
|
||||
Reference in New Issue
Block a user