1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-18 01:03: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:
Jake Fink
2023-09-20 15:57:01 -04:00
committed by GitHub
parent 020018085a
commit 8c06508435
30 changed files with 834 additions and 273 deletions

View File

@@ -1,4 +1,5 @@
import { ApiService } from "../../abstractions/api.service";
import { ClientType } from "../../enums";
import { KeysRequest } from "../../models/request/keys.request";
import { AppIdService } from "../../platform/abstractions/app-id.service";
import { CryptoService } from "../../platform/abstractions/crypto.service";
@@ -151,6 +152,16 @@ export abstract class LogInStrategy {
protected async processTokenResponse(response: IdentityTokenResponse): Promise<AuthResult> {
const result = new AuthResult();
// Old encryption keys must be migrated, but is currently only available on web.
// Other clients shouldn't continue the login process.
if (this.encryptionKeyMigrationRequired(response)) {
result.requiresEncryptionKeyMigration = true;
if (this.platformUtilsService.getClientType() !== ClientType.Web) {
return result;
}
}
result.resetMasterPassword = response.resetMasterPassword;
// Convert boolean to enum
@@ -166,9 +177,7 @@ export abstract class LogInStrategy {
}
await this.setMasterKey(response);
await this.setUserKey(response);
await this.setPrivateKey(response);
this.messagingService.send("loggedIn");
@@ -183,6 +192,12 @@ export abstract class LogInStrategy {
protected abstract setPrivateKey(response: IdentityTokenResponse): Promise<void>;
// Old accounts used master key for encryption. We are forcing migrations but only need to
// check on password logins
protected encryptionKeyMigrationRequired(response: IdentityTokenResponse): boolean {
return false;
}
protected async createKeyPairForOldAccount() {
try {
const [publicKey, privateKey] = await this.cryptoService.makeKeyPair();

View File

@@ -147,6 +147,10 @@ export class PasswordLogInStrategy extends LogInStrategy {
}
protected override async setUserKey(response: IdentityTokenResponse): Promise<void> {
// If migration is required, we won't have a user key to set yet.
if (this.encryptionKeyMigrationRequired(response)) {
return;
}
await this.cryptoService.setMasterKeyEncryptedUserKey(response.key);
const masterKey = await this.cryptoService.getMasterKey();
@@ -162,6 +166,10 @@ export class PasswordLogInStrategy extends LogInStrategy {
);
}
protected override encryptionKeyMigrationRequired(response: IdentityTokenResponse): boolean {
return !response.key;
}
private getMasterPasswordPolicyOptionsFromResponse(
response: IdentityTokenResponse | IdentityTwoFactorResponse | IdentityCaptchaResponse
): MasterPasswordPolicyOptions {

View File

@@ -17,6 +17,7 @@ export class AuthResult {
twoFactorProviders: Map<TwoFactorProviderType, { [key: string]: string }> = null;
ssoEmail2FaSessionToken?: string;
email: string;
requiresEncryptionKeyMigration: boolean;
get requiresCaptcha() {
return !Utils.isNullOrWhitespace(this.captchaSiteKey);