mirror of
https://github.com/bitwarden/browser
synced 2025-12-06 00:13:28 +00:00
[PM-23251] Remove low-kdf banner (#16511)
* Remove low-kdf banner * update tests
This commit is contained in:
@@ -1,14 +1,8 @@
|
||||
import { TestBed } from "@angular/core/testing";
|
||||
import { BehaviorSubject, firstValueFrom, take, timeout } from "rxjs";
|
||||
|
||||
import {
|
||||
AuthRequestServiceAbstraction,
|
||||
UserDecryptionOptions,
|
||||
UserDecryptionOptionsServiceAbstraction,
|
||||
} from "@bitwarden/auth/common";
|
||||
import { AuthRequestServiceAbstraction } from "@bitwarden/auth/common";
|
||||
import { AccountInfo, AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { DevicesServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices/devices.service.abstraction";
|
||||
import { DeviceView } from "@bitwarden/common/auth/abstractions/devices/views/device.view";
|
||||
import { AuthRequestResponse } from "@bitwarden/common/auth/models/response/auth-request.response";
|
||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||
import { DeviceType } from "@bitwarden/common/enums";
|
||||
@@ -18,7 +12,6 @@ import { StateProvider } from "@bitwarden/common/platform/state";
|
||||
import { FakeStateProvider, mockAccountServiceWith } from "@bitwarden/common/spec";
|
||||
import { UserId } from "@bitwarden/common/types/guid";
|
||||
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
|
||||
import { KdfConfigService, KdfType } from "@bitwarden/key-management";
|
||||
|
||||
import {
|
||||
PREMIUM_BANNER_REPROMPT_KEY,
|
||||
@@ -34,14 +27,9 @@ describe("VaultBannersService", () => {
|
||||
const fakeStateProvider = new FakeStateProvider(mockAccountServiceWith(userId));
|
||||
const getEmailVerified = jest.fn().mockResolvedValue(true);
|
||||
const lastSync$ = new BehaviorSubject<Date | null>(null);
|
||||
const userDecryptionOptions$ = new BehaviorSubject<UserDecryptionOptions>({
|
||||
hasMasterPassword: true,
|
||||
});
|
||||
const kdfConfig$ = new BehaviorSubject({ kdfType: KdfType.PBKDF2_SHA256, iterations: 600000 });
|
||||
const accounts$ = new BehaviorSubject<Record<UserId, AccountInfo>>({
|
||||
[userId]: { email: "test@bitwarden.com", emailVerified: true, name: "name" } as AccountInfo,
|
||||
});
|
||||
const devices$ = new BehaviorSubject<DeviceView[]>([]);
|
||||
const pendingAuthRequests$ = new BehaviorSubject<Array<AuthRequestResponse>>([]);
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -64,32 +52,14 @@ describe("VaultBannersService", () => {
|
||||
provide: StateProvider,
|
||||
useValue: fakeStateProvider,
|
||||
},
|
||||
{
|
||||
provide: PlatformUtilsService,
|
||||
useValue: { isSelfHost },
|
||||
},
|
||||
{
|
||||
provide: AccountService,
|
||||
useValue: { accounts$ },
|
||||
},
|
||||
{
|
||||
provide: KdfConfigService,
|
||||
useValue: { getKdfConfig$: () => kdfConfig$ },
|
||||
},
|
||||
{
|
||||
provide: SyncService,
|
||||
useValue: { lastSync$: () => lastSync$ },
|
||||
},
|
||||
{
|
||||
provide: UserDecryptionOptionsServiceAbstraction,
|
||||
useValue: {
|
||||
userDecryptionOptionsById$: () => userDecryptionOptions$,
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: DevicesServiceAbstraction,
|
||||
useValue: { getDevices$: () => devices$ },
|
||||
},
|
||||
{
|
||||
provide: AuthRequestServiceAbstraction,
|
||||
useValue: { getPendingAuthRequests$: () => pendingAuthRequests$ },
|
||||
@@ -197,45 +167,6 @@ describe("VaultBannersService", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("KDFSettings", () => {
|
||||
beforeEach(async () => {
|
||||
userDecryptionOptions$.next({ hasMasterPassword: true });
|
||||
kdfConfig$.next({ kdfType: KdfType.PBKDF2_SHA256, iterations: 599999 });
|
||||
});
|
||||
|
||||
it("shows low KDF iteration banner", async () => {
|
||||
service = TestBed.inject(VaultBannersService);
|
||||
|
||||
expect(await service.shouldShowLowKDFBanner(userId)).toBe(true);
|
||||
});
|
||||
|
||||
it("does not show low KDF iteration banner if KDF type is not PBKDF2_SHA256", async () => {
|
||||
kdfConfig$.next({ kdfType: KdfType.Argon2id, iterations: 600001 });
|
||||
|
||||
service = TestBed.inject(VaultBannersService);
|
||||
|
||||
expect(await service.shouldShowLowKDFBanner(userId)).toBe(false);
|
||||
});
|
||||
|
||||
it("does not show low KDF for iterations about 600,000", async () => {
|
||||
kdfConfig$.next({ kdfType: KdfType.PBKDF2_SHA256, iterations: 600001 });
|
||||
|
||||
service = TestBed.inject(VaultBannersService);
|
||||
|
||||
expect(await service.shouldShowLowKDFBanner(userId)).toBe(false);
|
||||
});
|
||||
|
||||
it("dismisses low KDF iteration banner", async () => {
|
||||
service = TestBed.inject(VaultBannersService);
|
||||
|
||||
expect(await service.shouldShowLowKDFBanner(userId)).toBe(true);
|
||||
|
||||
await service.dismissBanner(userId, VisibleVaultBanner.KDFSettings);
|
||||
|
||||
expect(await service.shouldShowLowKDFBanner(userId)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("OutdatedBrowser", () => {
|
||||
beforeEach(async () => {
|
||||
// Hardcode `MSIE` in userAgent string
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
import { Observable, combineLatest, firstValueFrom, map, filter, mergeMap, take } from "rxjs";
|
||||
|
||||
import {
|
||||
AuthRequestServiceAbstraction,
|
||||
UserDecryptionOptionsServiceAbstraction,
|
||||
} from "@bitwarden/auth/common";
|
||||
import { AuthRequestServiceAbstraction } from "@bitwarden/auth/common";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
@@ -18,10 +15,8 @@ import {
|
||||
import { UserId } from "@bitwarden/common/types/guid";
|
||||
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
|
||||
import { UnionOfValues } from "@bitwarden/common/vault/types/union-of-values";
|
||||
import { PBKDF2KdfConfig, KdfConfigService, KdfType } from "@bitwarden/key-management";
|
||||
|
||||
export const VisibleVaultBanner = {
|
||||
KDFSettings: "kdf-settings",
|
||||
OutdatedBrowser: "outdated-browser",
|
||||
Premium: "premium",
|
||||
VerifyEmail: "verify-email",
|
||||
@@ -64,9 +59,7 @@ export class VaultBannersService {
|
||||
private stateProvider: StateProvider,
|
||||
private billingAccountProfileStateService: BillingAccountProfileStateService,
|
||||
private platformUtilsService: PlatformUtilsService,
|
||||
private kdfConfigService: KdfConfigService,
|
||||
private syncService: SyncService,
|
||||
private userDecryptionOptionsService: UserDecryptionOptionsServiceAbstraction,
|
||||
private authRequestService: AuthRequestServiceAbstraction,
|
||||
) {}
|
||||
|
||||
@@ -133,21 +126,6 @@ export class VaultBannersService {
|
||||
return needsVerification && !alreadyDismissed;
|
||||
}
|
||||
|
||||
/** Returns true when the low KDF iteration banner should be shown */
|
||||
async shouldShowLowKDFBanner(userId: UserId): Promise<boolean> {
|
||||
const hasLowKDF = (
|
||||
await firstValueFrom(this.userDecryptionOptionsService.userDecryptionOptionsById$(userId))
|
||||
)?.hasMasterPassword
|
||||
? await this.isLowKdfIteration(userId)
|
||||
: false;
|
||||
|
||||
const alreadyDismissed = (await this.getBannerDismissedState(userId)).includes(
|
||||
VisibleVaultBanner.KDFSettings,
|
||||
);
|
||||
|
||||
return hasLowKDF && !alreadyDismissed;
|
||||
}
|
||||
|
||||
/** Dismiss the given banner and perform any respective side effects */
|
||||
async dismissBanner(userId: UserId, banner: SessionBanners): Promise<void> {
|
||||
if (banner === VisibleVaultBanner.Premium) {
|
||||
@@ -221,13 +199,4 @@ export class VaultBannersService {
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
private async isLowKdfIteration(userId: UserId) {
|
||||
const kdfConfig = await firstValueFrom(this.kdfConfigService.getKdfConfig$(userId));
|
||||
return (
|
||||
kdfConfig != null &&
|
||||
kdfConfig.kdfType === KdfType.PBKDF2_SHA256 &&
|
||||
kdfConfig.iterations < PBKDF2KdfConfig.ITERATIONS.defaultValue
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,18 +25,6 @@
|
||||
</a>
|
||||
</bit-banner>
|
||||
|
||||
<bit-banner
|
||||
id="kdf-settings-banner"
|
||||
bannerType="warning"
|
||||
*ngIf="visibleBanners.includes(VisibleVaultBanner.KDFSettings)"
|
||||
(onClose)="dismissBanner(VisibleVaultBanner.KDFSettings)"
|
||||
>
|
||||
{{ "lowKDFIterationsBanner" | i18n }}
|
||||
<a bitLink linkType="secondary" routerLink="/settings/security/security-keys">
|
||||
{{ "changeKDFSettings" | i18n }}
|
||||
</a>
|
||||
</bit-banner>
|
||||
|
||||
<bit-banner
|
||||
id="pending-auth-request-banner"
|
||||
bannerType="info"
|
||||
|
||||
@@ -35,7 +35,6 @@ describe("VaultBannersComponent", () => {
|
||||
shouldShowPremiumBanner$: jest.fn((userId: UserId) => premiumBanner$),
|
||||
shouldShowUpdateBrowserBanner: jest.fn(),
|
||||
shouldShowVerifyEmailBanner: jest.fn(),
|
||||
shouldShowLowKDFBanner: jest.fn(),
|
||||
shouldShowPendingAuthRequestBanner: jest.fn((userId: UserId) =>
|
||||
Promise.resolve(pendingAuthRequest$.value),
|
||||
),
|
||||
@@ -48,7 +47,6 @@ describe("VaultBannersComponent", () => {
|
||||
messageSubject = new Subject<{ command: string }>();
|
||||
bannerService.shouldShowUpdateBrowserBanner.mockResolvedValue(false);
|
||||
bannerService.shouldShowVerifyEmailBanner.mockResolvedValue(false);
|
||||
bannerService.shouldShowLowKDFBanner.mockResolvedValue(false);
|
||||
pendingAuthRequest$.next(false);
|
||||
premiumBanner$.next(false);
|
||||
|
||||
@@ -137,11 +135,6 @@ describe("VaultBannersComponent", () => {
|
||||
method: bannerService.shouldShowVerifyEmailBanner,
|
||||
banner: VisibleVaultBanner.VerifyEmail,
|
||||
},
|
||||
{
|
||||
name: "LowKDF",
|
||||
method: bannerService.shouldShowLowKDFBanner,
|
||||
banner: VisibleVaultBanner.KDFSettings,
|
||||
},
|
||||
].forEach(({ name, method, banner }) => {
|
||||
describe(name, () => {
|
||||
beforeEach(async () => {
|
||||
|
||||
@@ -100,14 +100,12 @@ export class VaultBannersComponent implements OnInit {
|
||||
const showBrowserOutdated =
|
||||
await this.vaultBannerService.shouldShowUpdateBrowserBanner(activeUserId);
|
||||
const showVerifyEmail = await this.vaultBannerService.shouldShowVerifyEmailBanner(activeUserId);
|
||||
const showLowKdf = await this.vaultBannerService.shouldShowLowKDFBanner(activeUserId);
|
||||
const showPendingAuthRequest =
|
||||
await this.vaultBannerService.shouldShowPendingAuthRequestBanner(activeUserId);
|
||||
|
||||
this.visibleBanners = [
|
||||
showBrowserOutdated ? VisibleVaultBanner.OutdatedBrowser : null,
|
||||
showVerifyEmail ? VisibleVaultBanner.VerifyEmail : null,
|
||||
showLowKdf ? VisibleVaultBanner.KDFSettings : null,
|
||||
showPendingAuthRequest ? VisibleVaultBanner.PendingAuthRequest : null,
|
||||
].filter((banner) => banner !== null);
|
||||
}
|
||||
|
||||
@@ -8408,12 +8408,6 @@
|
||||
"groupSlashUser": {
|
||||
"message": "Group/User"
|
||||
},
|
||||
"lowKdfIterations": {
|
||||
"message": "Low KDF Iterations"
|
||||
},
|
||||
"updateLowKdfIterationsDesc": {
|
||||
"message": "Update your encryption settings to meet new security recommendations and improve account protection."
|
||||
},
|
||||
"kdfSettingsChangeLogoutWarning": {
|
||||
"message": "Proceeding will log you out of all active sessions. You will need to log back in and complete two-step login, if any. We recommend exporting your vault before changing your encryption settings to prevent data loss."
|
||||
},
|
||||
@@ -10031,12 +10025,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"lowKDFIterationsBanner": {
|
||||
"message": "Low KDF iterations. Increase your iterations to improve the security of your account."
|
||||
},
|
||||
"changeKDFSettings": {
|
||||
"message": "Change KDF settings"
|
||||
},
|
||||
"secureYourInfrastructure": {
|
||||
"message": "Secure your infrastructure"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user