mirror of
https://github.com/bitwarden/browser
synced 2025-12-06 00:13:28 +00:00
[PM-18026] Implement forced, automatic KDF upgrades (#15937)
* Implement automatic kdf upgrades * Fix kdf config not being updated * Update legacy kdf state on master password unlock sync * Fix cli build * Fix * Deduplicate prompts * Fix dismiss time * Fix default kdf setting * Fix build * Undo changes * Fix test * Fix prettier * Fix test * Update libs/angular/src/key-management/encrypted-migration/encrypted-migrations-scheduler.service.ts Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com> * Update libs/common/src/key-management/master-password/abstractions/master-password.service.abstraction.ts Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com> * Update libs/angular/src/key-management/encrypted-migration/encrypted-migrations-scheduler.service.ts Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com> * Only sync when there is at least one migration * Relative imports * Add tech debt comment * Resolve inconsistent prefix * Clean up * Update docs * Use default PBKDF2 iteratinos instead of custom threshold * Undo type check * Fix build * Add comment * Cleanup * Cleanup * Address component feedback * Use isnullorwhitespace * Fix tests * Allow migration only on vault * Fix tests * Run prettier * Fix tests * Prevent await race condition * Fix min and default values in kdf migration * Run sync only when a migration was run * Update libs/common/src/key-management/encrypted-migrator/default-encrypted-migrator.ts Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com> * Fix link not being blue * Fix later button on browser --------- Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com>
This commit is contained in:
@@ -1406,6 +1406,27 @@
|
||||
"learnMore": {
|
||||
"message": "Learn more"
|
||||
},
|
||||
"migrationsFailed": {
|
||||
"message": "An error occurred updating the encryption settings."
|
||||
},
|
||||
"updateEncryptionSettingsTitle": {
|
||||
"message": "Update your encryption settings"
|
||||
},
|
||||
"updateEncryptionSettingsDesc": {
|
||||
"message": "The new recommended encryption settings will improve your account security. Enter your master password to update now."
|
||||
},
|
||||
"confirmIdentityToContinue": {
|
||||
"message": "Confirm your identity to continue"
|
||||
},
|
||||
"enterYourMasterPassword": {
|
||||
"message": "Enter your master password"
|
||||
},
|
||||
"updateSettings": {
|
||||
"message": "Update settings"
|
||||
},
|
||||
"later": {
|
||||
"message": "Later"
|
||||
},
|
||||
"authenticatorKeyTotp": {
|
||||
"message": "Authenticator key (TOTP)"
|
||||
},
|
||||
|
||||
@@ -31,6 +31,7 @@ import { TwoFactorService, TwoFactorApiService } from "@bitwarden/common/auth/tw
|
||||
import { ClientType } from "@bitwarden/common/enums";
|
||||
import { CryptoFunctionService } from "@bitwarden/common/key-management/crypto/abstractions/crypto-function.service";
|
||||
import { EncString } from "@bitwarden/common/key-management/crypto/models/enc-string";
|
||||
import { EncryptedMigrator } from "@bitwarden/common/key-management/encrypted-migrator/encrypted-migrator.abstraction";
|
||||
import { KeyConnectorService } from "@bitwarden/common/key-management/key-connector/abstractions/key-connector.service";
|
||||
import { MasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction";
|
||||
import { ErrorResponse } from "@bitwarden/common/models/response/error.response";
|
||||
@@ -81,6 +82,7 @@ export class LoginCommand {
|
||||
protected ssoUrlService: SsoUrlService,
|
||||
protected i18nService: I18nService,
|
||||
protected masterPasswordService: MasterPasswordServiceAbstraction,
|
||||
protected encryptedMigrator: EncryptedMigrator,
|
||||
) {}
|
||||
|
||||
async run(email: string, password: string, options: OptionValues) {
|
||||
@@ -367,6 +369,8 @@ export class LoginCommand {
|
||||
}
|
||||
}
|
||||
|
||||
await this.encryptedMigrator.runMigrations(response.userId, password);
|
||||
|
||||
return await this.handleSuccessResponse(response);
|
||||
} catch (e) {
|
||||
if (
|
||||
|
||||
@@ -182,6 +182,7 @@ export abstract class BaseProgram {
|
||||
this.serviceContainer.organizationApiService,
|
||||
this.serviceContainer.logout,
|
||||
this.serviceContainer.i18nService,
|
||||
this.serviceContainer.encryptedMigrator,
|
||||
this.serviceContainer.masterPasswordUnlockService,
|
||||
this.serviceContainer.configService,
|
||||
);
|
||||
|
||||
@@ -7,6 +7,7 @@ import { UserVerificationService } from "@bitwarden/common/auth/abstractions/use
|
||||
import { VerificationType } from "@bitwarden/common/auth/enums/verification-type";
|
||||
import { MasterPasswordVerificationResponse } from "@bitwarden/common/auth/types/verification";
|
||||
import { CryptoFunctionService } from "@bitwarden/common/key-management/crypto/abstractions/crypto-function.service";
|
||||
import { EncryptedMigrator } from "@bitwarden/common/key-management/encrypted-migrator/encrypted-migrator.abstraction";
|
||||
import { KeyConnectorService } from "@bitwarden/common/key-management/key-connector/abstractions/key-connector.service";
|
||||
import { MasterPasswordUnlockService } from "@bitwarden/common/key-management/master-password/abstractions/master-password-unlock.service";
|
||||
import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction";
|
||||
@@ -40,6 +41,7 @@ describe("UnlockCommand", () => {
|
||||
const organizationApiService = mock<OrganizationApiServiceAbstraction>();
|
||||
const logout = jest.fn();
|
||||
const i18nService = mock<I18nService>();
|
||||
const encryptedMigrator = mock<EncryptedMigrator>();
|
||||
const masterPasswordUnlockService = mock<MasterPasswordUnlockService>();
|
||||
const configService = mock<ConfigService>();
|
||||
|
||||
@@ -92,6 +94,7 @@ describe("UnlockCommand", () => {
|
||||
organizationApiService,
|
||||
logout,
|
||||
i18nService,
|
||||
encryptedMigrator,
|
||||
masterPasswordUnlockService,
|
||||
configService,
|
||||
);
|
||||
|
||||
@@ -9,6 +9,7 @@ import { VerificationType } from "@bitwarden/common/auth/enums/verification-type
|
||||
import { MasterPasswordVerification } from "@bitwarden/common/auth/types/verification";
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { CryptoFunctionService } from "@bitwarden/common/key-management/crypto/abstractions/crypto-function.service";
|
||||
import { EncryptedMigrator } from "@bitwarden/common/key-management/encrypted-migrator/encrypted-migrator.abstraction";
|
||||
import { KeyConnectorService } from "@bitwarden/common/key-management/key-connector/abstractions/key-connector.service";
|
||||
import { MasterPasswordUnlockService } from "@bitwarden/common/key-management/master-password/abstractions/master-password-unlock.service";
|
||||
import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction";
|
||||
@@ -38,6 +39,7 @@ export class UnlockCommand {
|
||||
private organizationApiService: OrganizationApiServiceAbstraction,
|
||||
private logout: () => Promise<void>,
|
||||
private i18nService: I18nService,
|
||||
private encryptedMigrator: EncryptedMigrator,
|
||||
private masterPasswordUnlockService: MasterPasswordUnlockService,
|
||||
private configService: ConfigService,
|
||||
) {}
|
||||
@@ -116,6 +118,8 @@ export class UnlockCommand {
|
||||
}
|
||||
}
|
||||
|
||||
await this.encryptedMigrator.runMigrations(userId, password);
|
||||
|
||||
return this.successResponse();
|
||||
}
|
||||
|
||||
|
||||
@@ -176,6 +176,7 @@ export class OssServeConfigurator {
|
||||
this.serviceContainer.organizationApiService,
|
||||
async () => await this.serviceContainer.logout(),
|
||||
this.serviceContainer.i18nService,
|
||||
this.serviceContainer.encryptedMigrator,
|
||||
this.serviceContainer.masterPasswordUnlockService,
|
||||
this.serviceContainer.configService,
|
||||
);
|
||||
|
||||
@@ -195,6 +195,7 @@ export class Program extends BaseProgram {
|
||||
this.serviceContainer.ssoUrlService,
|
||||
this.serviceContainer.i18nService,
|
||||
this.serviceContainer.masterPasswordService,
|
||||
this.serviceContainer.encryptedMigrator,
|
||||
);
|
||||
const response = await command.run(email, password, options);
|
||||
this.processResponse(response, true);
|
||||
@@ -311,6 +312,7 @@ export class Program extends BaseProgram {
|
||||
this.serviceContainer.organizationApiService,
|
||||
async () => await this.serviceContainer.logout(),
|
||||
this.serviceContainer.i18nService,
|
||||
this.serviceContainer.encryptedMigrator,
|
||||
this.serviceContainer.masterPasswordUnlockService,
|
||||
this.serviceContainer.configService,
|
||||
);
|
||||
|
||||
@@ -76,6 +76,10 @@ import {
|
||||
import { EncryptServiceImplementation } from "@bitwarden/common/key-management/crypto/services/encrypt.service.implementation";
|
||||
import { DeviceTrustServiceAbstraction } from "@bitwarden/common/key-management/device-trust/abstractions/device-trust.service.abstraction";
|
||||
import { DeviceTrustService } from "@bitwarden/common/key-management/device-trust/services/device-trust.service.implementation";
|
||||
import { DefaultEncryptedMigrator } from "@bitwarden/common/key-management/encrypted-migrator/default-encrypted-migrator";
|
||||
import { EncryptedMigrator } from "@bitwarden/common/key-management/encrypted-migrator/encrypted-migrator.abstraction";
|
||||
import { DefaultChangeKdfApiService } from "@bitwarden/common/key-management/kdf/change-kdf-api.service";
|
||||
import { DefaultChangeKdfService } from "@bitwarden/common/key-management/kdf/change-kdf.service";
|
||||
import { KeyConnectorService } from "@bitwarden/common/key-management/key-connector/services/key-connector.service";
|
||||
import { MasterPasswordUnlockService } from "@bitwarden/common/key-management/master-password/abstractions/master-password-unlock.service";
|
||||
import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction";
|
||||
@@ -324,6 +328,7 @@ export class ServiceContainer {
|
||||
cipherEncryptionService: CipherEncryptionService;
|
||||
restrictedItemTypesService: RestrictedItemTypesService;
|
||||
cliRestrictedItemTypesService: CliRestrictedItemTypesService;
|
||||
encryptedMigrator: EncryptedMigrator;
|
||||
securityStateService: SecurityStateService;
|
||||
masterPasswordUnlockService: MasterPasswordUnlockService;
|
||||
cipherArchiveService: CipherArchiveService;
|
||||
@@ -975,6 +980,16 @@ export class ServiceContainer {
|
||||
);
|
||||
|
||||
this.masterPasswordApiService = new MasterPasswordApiService(this.apiService, this.logService);
|
||||
const changeKdfApiService = new DefaultChangeKdfApiService(this.apiService);
|
||||
const changeKdfService = new DefaultChangeKdfService(changeKdfApiService, this.sdkService);
|
||||
this.encryptedMigrator = new DefaultEncryptedMigrator(
|
||||
this.kdfConfigService,
|
||||
changeKdfService,
|
||||
this.logService,
|
||||
this.configService,
|
||||
this.masterPasswordService,
|
||||
this.syncService,
|
||||
);
|
||||
}
|
||||
|
||||
async logout() {
|
||||
|
||||
@@ -1093,6 +1093,24 @@
|
||||
"learnMore": {
|
||||
"message": "Learn more"
|
||||
},
|
||||
"migrationsFailed": {
|
||||
"message": "An error occurred updating the encryption settings."
|
||||
},
|
||||
"updateEncryptionSettingsTitle": {
|
||||
"message": "Update your encryption settings"
|
||||
},
|
||||
"updateEncryptionSettingsDesc": {
|
||||
"message": "The new recommended encryption settings will improve your account security. Enter your master password to update now."
|
||||
},
|
||||
"confirmIdentityToContinue": {
|
||||
"message": "Confirm your identity to continue"
|
||||
},
|
||||
"enterYourMasterPassword": {
|
||||
"message": "Enter your master password"
|
||||
},
|
||||
"updateSettings": {
|
||||
"message": "Update settings"
|
||||
},
|
||||
"featureUnavailable": {
|
||||
"message": "Feature unavailable"
|
||||
},
|
||||
|
||||
@@ -108,7 +108,7 @@ export class RecoverTwoFactorComponent implements OnInit {
|
||||
message: this.i18nService.t("twoStepRecoverDisabled"),
|
||||
});
|
||||
|
||||
await this.loginSuccessHandlerService.run(authResult.userId);
|
||||
await this.loginSuccessHandlerService.run(authResult.userId, this.masterPassword);
|
||||
|
||||
await this.router.navigate(["/settings/security/two-factor"]);
|
||||
} catch (error: unknown) {
|
||||
|
||||
@@ -4,7 +4,7 @@ import { mock, MockProxy } from "jest-mock-extended";
|
||||
import { of } from "rxjs";
|
||||
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { ChangeKdfService } from "@bitwarden/common/key-management/kdf/change-kdf-service.abstraction";
|
||||
import { ChangeKdfService } from "@bitwarden/common/key-management/kdf/change-kdf.service.abstraction";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||
|
||||
@@ -5,7 +5,7 @@ import { firstValueFrom, Observable } from "rxjs";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { ChangeKdfService } from "@bitwarden/common/key-management/kdf/change-kdf-service.abstraction";
|
||||
import { ChangeKdfService } from "@bitwarden/common/key-management/kdf/change-kdf.service.abstraction";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||
|
||||
@@ -4621,6 +4621,24 @@
|
||||
"learnMore": {
|
||||
"message": "Learn more"
|
||||
},
|
||||
"migrationsFailed": {
|
||||
"message": "An error occurred updating the encryption settings."
|
||||
},
|
||||
"updateEncryptionSettingsTitle": {
|
||||
"message": "Update your encryption settings"
|
||||
},
|
||||
"updateEncryptionSettingsDesc": {
|
||||
"message": "The new recommended encryption settings will improve your account security. Enter your master password to update now."
|
||||
},
|
||||
"confirmIdentityToContinue": {
|
||||
"message": "Confirm your identity to continue"
|
||||
},
|
||||
"enterYourMasterPassword": {
|
||||
"message": "Enter your master password"
|
||||
},
|
||||
"updateSettings": {
|
||||
"message": "Update settings"
|
||||
},
|
||||
"deleteRecoverDesc": {
|
||||
"message": "Enter your email address below to recover and delete your account."
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user