1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-11 05:43:41 +00:00

[PM-22695] Remove unused vault service (#16134)

* [PM-22695] Remove obsolete browser vault filter service

* [PM-22695] Remove obsolete vault browser state service
This commit is contained in:
Shane Melton
2025-08-25 14:50:54 -07:00
committed by GitHub
parent ae2259db2f
commit e10d13faa8
6 changed files with 1 additions and 320 deletions

View File

@@ -299,7 +299,6 @@ import { OffscreenStorageService } from "../platform/storage/offscreen-storage.s
import { SyncServiceListener } from "../platform/sync/sync-service.listener";
import { BrowserSystemNotificationService } from "../platform/system-notifications/browser-system-notification.service";
import { fromChromeRuntimeMessaging } from "../platform/utils/from-chrome-runtime-messaging";
import { VaultFilterService } from "../vault/services/vault-filter.service";
import CommandsBackground from "./commands.background";
import IdleBackground from "./idle.background";
@@ -364,7 +363,6 @@ export default class MainBackground {
providerService: ProviderServiceAbstraction;
keyConnectorService: KeyConnectorServiceAbstraction;
userVerificationService: UserVerificationServiceAbstraction;
vaultFilterService: VaultFilterService;
usernameGenerationService: UsernameGenerationServiceAbstraction;
encryptService: EncryptService;
folderApiService: FolderApiServiceAbstraction;
@@ -919,18 +917,6 @@ export default class MainBackground {
this.biometricsService,
);
this.vaultFilterService = new VaultFilterService(
this.organizationService,
this.folderService,
this.cipherService,
this.collectionService,
this.policyService,
this.stateProvider,
this.accountService,
this.configService,
this.i18nService,
);
this.vaultSettingsService = new VaultSettingsService(
this.stateProvider,
this.restrictedItemTypesService,
@@ -1600,7 +1586,6 @@ export default class MainBackground {
this.cipherService.clear(userBeingLoggedOut),
this.folderService.clear(userBeingLoggedOut),
this.vaultTimeoutSettingsService.clear(userBeingLoggedOut),
this.vaultFilterService.clear(),
this.biometricStateService.logout(userBeingLoggedOut),
this.popupViewCacheBackgroundService.clearState(),
/* We intentionally do not clear:

View File

@@ -49,7 +49,6 @@ import { BiometricsService, BiometricStateService, KeyService } from "@bitwarden
import { PopupCompactModeService } from "../platform/popup/layout/popup-compact-mode.service";
import { PopupSizeService } from "../platform/popup/layout/popup-size.service";
import { initPopupClosedListener } from "../platform/services/popup-view-cache-background.service";
import { VaultBrowserStateService } from "../vault/services/vault-browser-state.service";
import { routerTransition } from "./app-routing.animations";
import { DesktopSyncVerificationDialogComponent } from "./components/desktop-sync-verification-dialog.component";
@@ -103,7 +102,6 @@ export class AppComponent implements OnInit, OnDestroy {
private i18nService: I18nService,
private router: Router,
private readonly tokenService: TokenService,
private vaultBrowserStateService: VaultBrowserStateService,
private cipherService: CipherService,
private changeDetectorRef: ChangeDetectorRef,
private ngZone: NgZone,
@@ -135,10 +133,6 @@ export class AppComponent implements OnInit, OnDestroy {
this.compactModeService.init();
await this.popupSizeService.setHeight();
// Component states must not persist between closing and reopening the popup, otherwise they become dead objects
// Clear them aggressively to make sure this doesn't occur
await this.clearComponentStates();
this.accountService.activeAccount$.pipe(takeUntil(this.destroy$)).subscribe((account) => {
this.activeUserId = account?.id;
});
@@ -249,13 +243,6 @@ export class AppComponent implements OnInit, OnDestroy {
this.router.events.pipe(takeUntil(this.destroy$)).subscribe(async (event) => {
if (event instanceof NavigationEnd) {
const url = event.urlAfterRedirects || event.url || "";
if (
url.startsWith("/tabs/") &&
(window as any).previousPopupUrl != null &&
(window as any).previousPopupUrl.startsWith("/tabs/")
) {
await this.clearComponentStates();
}
if (url.startsWith("/tabs/")) {
await this.cipherService.setAddEditCipherInfo(null, this.activeUserId);
}
@@ -320,20 +307,6 @@ export class AppComponent implements OnInit, OnDestroy {
return firstValueFrom(dialogRef.closed);
}
private async clearComponentStates() {
if (this.activeUserId == null) {
return;
}
if (!(await firstValueFrom(this.tokenService.hasAccessToken$(this.activeUserId)))) {
return;
}
await Promise.all([
this.vaultBrowserStateService.setBrowserGroupingsComponentState(null),
this.vaultBrowserStateService.setBrowserVaultItemsComponentState(null),
]);
}
// Displaying toasts isn't super useful on the popup due to the reloads we do.
// However, it is visible for a moment on the FF sidebar logout.
private async displayLogoutReason(logoutReason: LogoutReason) {

View File

@@ -39,7 +39,6 @@ import {
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { EventCollectionService as EventCollectionServiceAbstraction } from "@bitwarden/common/abstractions/event/event-collection.service";
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
import { DefaultOrganizationService } from "@bitwarden/common/admin-console/services/organization/default-organization.service";
import {
AccountService,
AccountService as AccountServiceAbstraction,
@@ -112,10 +111,7 @@ import { SendApiService } from "@bitwarden/common/tools/send/services/send-api.s
import { InternalSendService } from "@bitwarden/common/tools/send/services/send.service.abstraction";
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
import { FolderApiServiceAbstraction } from "@bitwarden/common/vault/abstractions/folder/folder-api.service.abstraction";
import {
FolderService as FolderServiceAbstraction,
InternalFolderService,
} from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction";
import { InternalFolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction";
import { TotpService as TotpServiceAbstraction } from "@bitwarden/common/vault/abstractions/totp.service";
import { RestrictedItemTypesService } from "@bitwarden/common/vault/services/restricted-item-types.service";
import { TotpService } from "@bitwarden/common/vault/services/totp.service";
@@ -186,8 +182,6 @@ import { BrowserSystemNotificationService } from "../../platform/system-notifica
import { fromChromeRuntimeMessaging } from "../../platform/utils/from-chrome-runtime-messaging";
import { FilePopoutUtilsService } from "../../tools/popup/services/file-popout-utils.service";
import { Fido2UserVerificationService } from "../../vault/services/fido2-user-verification.service";
import { VaultBrowserStateService } from "../../vault/services/vault-browser-state.service";
import { VaultFilterService } from "../../vault/services/vault-filter.service";
import { ExtensionAnonLayoutWrapperDataService } from "../components/extension-anon-layout-wrapper/extension-anon-layout-wrapper-data.service";
import { DebounceNavigationService } from "./debounce-navigation.service";
@@ -402,21 +396,6 @@ const safeProviders: SafeProvider[] = [
useClass: ForegroundVaultTimeoutService,
deps: [MessagingServiceAbstraction],
}),
safeProvider({
provide: VaultFilterService,
useClass: VaultFilterService,
deps: [
DefaultOrganizationService,
FolderServiceAbstraction,
CipherService,
CollectionService,
PolicyService,
StateProvider,
AccountServiceAbstraction,
ConfigService,
I18nServiceAbstraction,
],
}),
safeProvider({
provide: SECURE_STORAGE,
useExisting: AbstractStorageService, // Secure storage is not available in the browser, so we use normal storage instead and warn users when it is used.
@@ -454,13 +433,6 @@ const safeProviders: SafeProvider[] = [
provide: OBSERVABLE_DISK_STORAGE,
useExisting: AbstractStorageService,
}),
safeProvider({
provide: VaultBrowserStateService,
useFactory: (stateProvider: StateProvider) => {
return new VaultBrowserStateService(stateProvider);
},
deps: [StateProvider],
}),
safeProvider({
provide: FileDownloadService,
useClass: BrowserFileDownloadService,

View File

@@ -1,87 +0,0 @@
import {
FakeAccountService,
mockAccountServiceWith,
} from "@bitwarden/common/../spec/fake-account-service";
import { FakeStateProvider } from "@bitwarden/common/../spec/fake-state-provider";
import { Jsonify } from "type-fest";
import { Utils } from "@bitwarden/common/platform/misc/utils";
import { UserId } from "@bitwarden/common/types/guid";
import { CipherType } from "@bitwarden/common/vault/enums";
import { BrowserComponentState } from "../../models/browserComponentState";
import { BrowserGroupingsComponentState } from "../../models/browserGroupingsComponentState";
import {
VAULT_BROWSER_COMPONENT,
VAULT_BROWSER_GROUPINGS_COMPONENT,
VaultBrowserStateService,
} from "./vault-browser-state.service";
describe("Vault Browser State Service", () => {
let stateProvider: FakeStateProvider;
let accountService: FakeAccountService;
let stateService: VaultBrowserStateService;
const mockUserId = Utils.newGuid() as UserId;
beforeEach(() => {
accountService = mockAccountServiceWith(mockUserId);
stateProvider = new FakeStateProvider(accountService);
stateService = new VaultBrowserStateService(stateProvider);
});
describe("getBrowserGroupingsComponentState", () => {
it("should return a BrowserGroupingsComponentState", async () => {
await stateService.setBrowserGroupingsComponentState(new BrowserGroupingsComponentState());
const actual = await stateService.getBrowserGroupingsComponentState();
expect(actual).toBeInstanceOf(BrowserGroupingsComponentState);
});
it("should deserialize BrowserGroupingsComponentState", () => {
const sut = VAULT_BROWSER_GROUPINGS_COMPONENT;
const expectedState = {
deletedCount: 0,
collectionCounts: new Map<string, number>(),
folderCounts: new Map<string, number>(),
typeCounts: new Map<CipherType, number>(),
};
const result = sut.deserializer(
JSON.parse(JSON.stringify(expectedState)) as Jsonify<BrowserGroupingsComponentState>,
);
expect(result).toEqual(expectedState);
});
});
describe("getBrowserVaultItemsComponentState", () => {
it("should deserialize BrowserComponentState", () => {
const sut = VAULT_BROWSER_COMPONENT;
const expectedState = {
scrollY: 0,
searchText: "test",
};
const result = sut.deserializer(JSON.parse(JSON.stringify(expectedState)));
expect(result).toEqual(expectedState);
});
it("should return a BrowserComponentState", async () => {
const componentState = new BrowserComponentState();
componentState.scrollY = 0;
componentState.searchText = "test";
await stateService.setBrowserVaultItemsComponentState(componentState);
const actual = await stateService.getBrowserVaultItemsComponentState();
expect(actual).toStrictEqual(componentState);
});
});
});

View File

@@ -1,74 +0,0 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { Observable, firstValueFrom } from "rxjs";
import { Jsonify } from "type-fest";
import {
ActiveUserState,
StateProvider,
UserKeyDefinition,
VAULT_BROWSER_MEMORY,
} from "@bitwarden/common/platform/state";
import { BrowserComponentState } from "../../models/browserComponentState";
import { BrowserGroupingsComponentState } from "../../models/browserGroupingsComponentState";
export const VAULT_BROWSER_GROUPINGS_COMPONENT =
new UserKeyDefinition<BrowserGroupingsComponentState>(
VAULT_BROWSER_MEMORY,
"vault_browser_groupings_component",
{
deserializer: (obj: Jsonify<BrowserGroupingsComponentState>) =>
BrowserGroupingsComponentState.fromJSON(obj),
clearOn: ["logout", "lock"],
},
);
export const VAULT_BROWSER_COMPONENT = new UserKeyDefinition<BrowserComponentState>(
VAULT_BROWSER_MEMORY,
"vault_browser_component",
{
deserializer: (obj: Jsonify<BrowserComponentState>) => BrowserComponentState.fromJSON(obj),
clearOn: ["logout", "lock"],
},
);
export class VaultBrowserStateService {
vaultBrowserGroupingsComponentState$: Observable<BrowserGroupingsComponentState>;
vaultBrowserComponentState$: Observable<BrowserComponentState>;
private activeUserVaultBrowserGroupingsComponentState: ActiveUserState<BrowserGroupingsComponentState>;
private activeUserVaultBrowserComponentState: ActiveUserState<BrowserComponentState>;
constructor(protected stateProvider: StateProvider) {
this.activeUserVaultBrowserGroupingsComponentState = this.stateProvider.getActive(
VAULT_BROWSER_GROUPINGS_COMPONENT,
);
this.activeUserVaultBrowserComponentState =
this.stateProvider.getActive(VAULT_BROWSER_COMPONENT);
this.vaultBrowserGroupingsComponentState$ =
this.activeUserVaultBrowserGroupingsComponentState.state$;
this.vaultBrowserComponentState$ = this.activeUserVaultBrowserComponentState.state$;
}
async getBrowserGroupingsComponentState(): Promise<BrowserGroupingsComponentState> {
return await firstValueFrom(this.vaultBrowserGroupingsComponentState$);
}
async setBrowserGroupingsComponentState(value: BrowserGroupingsComponentState): Promise<void> {
await this.activeUserVaultBrowserGroupingsComponentState.update(() => value, {
shouldUpdate: (current) => !(current == null && value == null),
});
}
async getBrowserVaultItemsComponentState(): Promise<BrowserComponentState> {
return await firstValueFrom(this.vaultBrowserComponentState$);
}
async setBrowserVaultItemsComponentState(value: BrowserComponentState): Promise<void> {
await this.activeUserVaultBrowserComponentState.update(() => value, {
shouldUpdate: (current) => !(current == null && value == null),
});
}
}

View File

@@ -1,88 +0,0 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { CollectionService } from "@bitwarden/admin-console/common";
import { VaultFilter } from "@bitwarden/angular/vault/vault-filter/models/vault-filter.model";
import { VaultFilterService as BaseVaultFilterService } from "@bitwarden/angular/vault/vault-filter/services/vault-filter.service";
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { StateProvider } from "@bitwarden/common/platform/state";
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction";
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
export class VaultFilterService extends BaseVaultFilterService {
vaultFilter: VaultFilter = new VaultFilter();
allVaults = "allVaults";
myVault = "myVault";
constructor(
organizationService: OrganizationService,
folderService: FolderService,
cipherService: CipherService,
collectionService: CollectionService,
policyService: PolicyService,
stateProvider: StateProvider,
accountService: AccountService,
configService: ConfigService,
i18nService: I18nService,
) {
super(
organizationService,
folderService,
cipherService,
collectionService,
policyService,
stateProvider,
accountService,
configService,
i18nService,
);
this.vaultFilter.myVaultOnly = false;
this.vaultFilter.selectedOrganizationId = null;
accountService.activeAccount$.subscribe((account) => {
this.setVaultFilter(this.allVaults);
});
}
getVaultFilter() {
return this.vaultFilter;
}
setVaultFilter(filter: string) {
if (filter === this.allVaults) {
this.vaultFilter.myVaultOnly = false;
this.vaultFilter.selectedOrganizationId = null;
} else if (filter === this.myVault) {
this.vaultFilter.myVaultOnly = true;
this.vaultFilter.selectedOrganizationId = null;
} else {
this.vaultFilter.myVaultOnly = false;
this.vaultFilter.selectedOrganizationId = filter;
}
}
clear() {
this.setVaultFilter(this.allVaults);
}
filterCipherForSelectedVault(cipher: CipherView) {
if (!this.vaultFilter.selectedOrganizationId && !this.vaultFilter.myVaultOnly) {
return false;
}
if (this.vaultFilter.selectedOrganizationId) {
if (cipher.organizationId === this.vaultFilter.selectedOrganizationId) {
return false;
}
} else if (this.vaultFilter.myVaultOnly) {
if (!cipher.organizationId) {
return false;
}
}
return true;
}
}