mirror of
https://github.com/bitwarden/browser
synced 2025-12-12 22:33:35 +00:00
[PM-3726] Force migration of legacy user's encryption key (#6195)
* [PM-3726] migrate legacy user's encryption key * [PM-3726] add 2fa support and pr feedback * [PM-3726] revert launch.json & webpack.config changes * [PM-3726] remove update key component - also remove card in vault since legacy users can't login * [PM-3726] Fix i18n & PR feedback * [PM-3726] make standalone component * [PM-3726] linter * [PM-3726] missing await * [PM-3726] logout legacy users with vault timeout to never * [PM-3726] add await * [PM-3726] skip auto key migration for legacy users * [PM-3726] pr feedback * [PM-3726] move check for web into migrate method --------- Co-authored-by: Jared Snider <116684653+JaredSnider-Bitwarden@users.noreply.github.com>
This commit is contained in:
@@ -141,6 +141,8 @@ export class LoginComponent extends CaptchaProtectedComponent implements OnInit
|
||||
await this.loginService.saveEmailSettings();
|
||||
if (this.handleCaptchaRequired(response)) {
|
||||
return;
|
||||
} else if (this.handleMigrateEncryptionKey(response)) {
|
||||
return;
|
||||
} else if (response.requiresTwoFactor) {
|
||||
if (this.onSuccessfulLoginTwoFactorNavigate != null) {
|
||||
this.onSuccessfulLoginTwoFactorNavigate();
|
||||
@@ -272,6 +274,21 @@ export class LoginComponent extends CaptchaProtectedComponent implements OnInit
|
||||
await this.loginService.saveEmailSettings();
|
||||
}
|
||||
|
||||
// Legacy accounts used the master key to encrypt data. Migration is required
|
||||
// but only performed on web
|
||||
protected handleMigrateEncryptionKey(result: AuthResult): boolean {
|
||||
if (!result.requiresEncryptionKeyMigration) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.platformUtilsService.showToast(
|
||||
"error",
|
||||
this.i18nService.t("errorOccured"),
|
||||
this.i18nService.t("encryptionKeyMigrationRequired")
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
private getErrorToastMessage() {
|
||||
const error: AllValidationErrors = this.formValidationErrorService
|
||||
.getFormValidationErrors(this.formGroup.controls)
|
||||
|
||||
@@ -215,9 +215,24 @@ export class TwoFactorComponent extends CaptchaProtectedComponent implements OnI
|
||||
await this.handleLoginResponse(authResult);
|
||||
}
|
||||
|
||||
protected handleMigrateEncryptionKey(result: AuthResult): boolean {
|
||||
if (!result.requiresEncryptionKeyMigration) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.platformUtilsService.showToast(
|
||||
"error",
|
||||
this.i18nService.t("errorOccured"),
|
||||
this.i18nService.t("encryptionKeyMigrationRequired")
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
private async handleLoginResponse(authResult: AuthResult) {
|
||||
if (this.handleCaptchaRequired(authResult)) {
|
||||
return;
|
||||
} else if (this.handleMigrateEncryptionKey(authResult)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.loginService.clearValues();
|
||||
|
||||
@@ -10,7 +10,10 @@ import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
|
||||
import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction";
|
||||
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
||||
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
||||
import { ClientType } from "@bitwarden/common/enums";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
|
||||
/**
|
||||
* Only allow access to this route if the vault is locked.
|
||||
@@ -25,9 +28,21 @@ export function lockGuard(): CanActivateFn {
|
||||
const authService = inject(AuthService);
|
||||
const cryptoService = inject(CryptoService);
|
||||
const deviceTrustCryptoService = inject(DeviceTrustCryptoServiceAbstraction);
|
||||
const platformUtilService = inject(PlatformUtilsService);
|
||||
const messagingService = inject(MessagingService);
|
||||
const router = inject(Router);
|
||||
const userVerificationService = inject(UserVerificationService);
|
||||
|
||||
// If legacy user on web, redirect to migration page
|
||||
if (await cryptoService.isLegacyUser()) {
|
||||
if (platformUtilService.getClientType() === ClientType.Web) {
|
||||
return router.createUrlTree(["migrate-legacy-encryption"]);
|
||||
}
|
||||
// Log out legacy users on other clients
|
||||
messagingService.send("logout");
|
||||
return false;
|
||||
}
|
||||
|
||||
const authStatus = await authService.getAuthStatus();
|
||||
if (authStatus !== AuthenticationStatus.Locked) {
|
||||
return router.createUrlTree(["/"]);
|
||||
|
||||
@@ -24,7 +24,6 @@ export class AttachmentsComponent implements OnInit {
|
||||
|
||||
cipher: CipherView;
|
||||
cipherDomain: Cipher;
|
||||
hasUpdatedKey: boolean;
|
||||
canAccessAttachments: boolean;
|
||||
formPromise: Promise<any>;
|
||||
deletePromises: { [id: string]: Promise<any> } = {};
|
||||
@@ -50,15 +49,6 @@ export class AttachmentsComponent implements OnInit {
|
||||
}
|
||||
|
||||
async submit() {
|
||||
if (!this.hasUpdatedKey) {
|
||||
this.platformUtilsService.showToast(
|
||||
"error",
|
||||
this.i18nService.t("errorOccurred"),
|
||||
this.i18nService.t("updateKey")
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const fileEl = document.getElementById("file") as HTMLInputElement;
|
||||
const files = fileEl.files;
|
||||
if (files == null || files.length === 0) {
|
||||
@@ -191,7 +181,6 @@ export class AttachmentsComponent implements OnInit {
|
||||
this.cipherDomain = await this.loadCipher();
|
||||
this.cipher = await this.cipherDomain.decrypt();
|
||||
|
||||
this.hasUpdatedKey = await this.cryptoService.hasUserKey();
|
||||
const canAccessPremium = await this.stateService.getCanAccessPremium();
|
||||
this.canAccessAttachments = canAccessPremium || this.cipher.organizationId != null;
|
||||
|
||||
@@ -206,19 +195,6 @@ export class AttachmentsComponent implements OnInit {
|
||||
if (confirmed) {
|
||||
this.platformUtilsService.launchUri("https://vault.bitwarden.com/#/?premium=purchase");
|
||||
}
|
||||
} else if (!this.hasUpdatedKey) {
|
||||
const confirmed = await this.dialogService.openSimpleDialog({
|
||||
title: { key: "featureUnavailable" },
|
||||
content: { key: "updateKey" },
|
||||
acceptButtonText: { key: "learnMore" },
|
||||
type: "warning",
|
||||
});
|
||||
|
||||
if (confirmed) {
|
||||
this.platformUtilsService.launchUri(
|
||||
"https://bitwarden.com/help/account-encryption-key/#rotate-your-encryption-key"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user