mirror of
https://github.com/bitwarden/browser
synced 2025-12-10 05:13:29 +00:00
[PM-7604] Require target UserID for KdfConfigService (#14380)
* Require userId for KdfConfigService * Update auth team callers * Update tools team callers
This commit is contained in:
@@ -5,7 +5,7 @@ import * as http from "http";
|
||||
import { OptionValues } from "commander";
|
||||
import * as inquirer from "inquirer";
|
||||
import Separator from "inquirer/lib/objects/separator";
|
||||
import { firstValueFrom, map, switchMap } from "rxjs";
|
||||
import { firstValueFrom, map } from "rxjs";
|
||||
|
||||
import {
|
||||
LoginStrategyServiceAbstraction,
|
||||
@@ -29,7 +29,6 @@ import { TokenTwoFactorRequest } from "@bitwarden/common/auth/models/request/ide
|
||||
import { PasswordRequest } from "@bitwarden/common/auth/models/request/password.request";
|
||||
import { TwoFactorEmailRequest } from "@bitwarden/common/auth/models/request/two-factor-email.request";
|
||||
import { UpdateTempPasswordRequest } from "@bitwarden/common/auth/models/request/update-temp-password.request";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { ClientType } from "@bitwarden/common/enums";
|
||||
import { CryptoFunctionService } from "@bitwarden/common/key-management/crypto/abstractions/crypto-function.service";
|
||||
import { KeyConnectorService } from "@bitwarden/common/key-management/key-connector/abstractions/key-connector.service";
|
||||
@@ -40,6 +39,7 @@ import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
|
||||
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
|
||||
import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength";
|
||||
import { UserId } from "@bitwarden/common/types/guid";
|
||||
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
|
||||
import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy";
|
||||
import { KdfConfigService, KeyService } from "@bitwarden/key-management";
|
||||
@@ -367,9 +367,9 @@ export class LoginCommand {
|
||||
clientSecret == null
|
||||
) {
|
||||
if (response.forcePasswordReset === ForceSetPasswordReason.AdminForcePasswordReset) {
|
||||
return await this.updateTempPassword();
|
||||
return await this.updateTempPassword(response.userId);
|
||||
} else if (response.forcePasswordReset === ForceSetPasswordReason.WeakMasterPassword) {
|
||||
return await this.updateWeakPassword(password);
|
||||
return await this.updateWeakPassword(response.userId, password);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -431,7 +431,7 @@ export class LoginCommand {
|
||||
return Response.success(res);
|
||||
}
|
||||
|
||||
private async updateWeakPassword(currentPassword: string) {
|
||||
private async updateWeakPassword(userId: UserId, currentPassword: string) {
|
||||
// If no interaction available, alert user to use web vault
|
||||
if (!this.canInteract) {
|
||||
await this.logoutCallback();
|
||||
@@ -448,6 +448,7 @@ export class LoginCommand {
|
||||
|
||||
try {
|
||||
const { newPasswordHash, newUserKey, hint } = await this.collectNewMasterPasswordDetails(
|
||||
userId,
|
||||
"Your master password does not meet one or more of your organization policies. In order to access the vault, you must update your master password now.",
|
||||
);
|
||||
|
||||
@@ -469,7 +470,7 @@ export class LoginCommand {
|
||||
}
|
||||
}
|
||||
|
||||
private async updateTempPassword() {
|
||||
private async updateTempPassword(userId: UserId) {
|
||||
// If no interaction available, alert user to use web vault
|
||||
if (!this.canInteract) {
|
||||
await this.logoutCallback();
|
||||
@@ -486,6 +487,7 @@ export class LoginCommand {
|
||||
|
||||
try {
|
||||
const { newPasswordHash, newUserKey, hint } = await this.collectNewMasterPasswordDetails(
|
||||
userId,
|
||||
"An organization administrator recently changed your master password. In order to access the vault, you must update your master password now.",
|
||||
);
|
||||
|
||||
@@ -510,10 +512,12 @@ export class LoginCommand {
|
||||
* Collect new master password and hint from the CLI. The collected password
|
||||
* is validated against any applicable master password policies, a new master
|
||||
* key is generated, and we use it to re-encrypt the user key
|
||||
* @param userId - User ID of the account
|
||||
* @param prompt - Message that is displayed during the initial prompt
|
||||
* @param error
|
||||
*/
|
||||
private async collectNewMasterPasswordDetails(
|
||||
userId: UserId,
|
||||
prompt: string,
|
||||
error?: string,
|
||||
): Promise<{
|
||||
@@ -539,11 +543,12 @@ export class LoginCommand {
|
||||
|
||||
// Master Password Validation
|
||||
if (masterPassword == null || masterPassword === "") {
|
||||
return this.collectNewMasterPasswordDetails(prompt, "Master password is required.\n");
|
||||
return this.collectNewMasterPasswordDetails(userId, prompt, "Master password is required.\n");
|
||||
}
|
||||
|
||||
if (masterPassword.length < Utils.minimumPasswordLength) {
|
||||
return this.collectNewMasterPasswordDetails(
|
||||
userId,
|
||||
prompt,
|
||||
`Master password must be at least ${Utils.minimumPasswordLength} characters long.\n`,
|
||||
);
|
||||
@@ -556,10 +561,7 @@ export class LoginCommand {
|
||||
);
|
||||
|
||||
const enforcedPolicyOptions = await firstValueFrom(
|
||||
this.accountService.activeAccount$.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) => this.policyService.masterPasswordPolicyOptions$(userId)),
|
||||
),
|
||||
this.policyService.masterPasswordPolicyOptions$(userId),
|
||||
);
|
||||
|
||||
// Verify master password meets policy requirements
|
||||
@@ -572,6 +574,7 @@ export class LoginCommand {
|
||||
)
|
||||
) {
|
||||
return this.collectNewMasterPasswordDetails(
|
||||
userId,
|
||||
prompt,
|
||||
"Your new master password does not meet the policy requirements.\n",
|
||||
);
|
||||
@@ -589,6 +592,7 @@ export class LoginCommand {
|
||||
// Re-type Validation
|
||||
if (masterPassword !== masterPasswordRetype) {
|
||||
return this.collectNewMasterPasswordDetails(
|
||||
userId,
|
||||
prompt,
|
||||
"Master password confirmation does not match.\n",
|
||||
);
|
||||
@@ -601,7 +605,7 @@ export class LoginCommand {
|
||||
message: "Master Password Hint (optional):",
|
||||
});
|
||||
const masterPasswordHint = hint.input;
|
||||
const kdfConfig = await this.kdfConfigService.getKdfConfig();
|
||||
const kdfConfig = await this.kdfConfigService.getKdfConfig(userId);
|
||||
|
||||
// Create new key and hash new password
|
||||
const newMasterKey = await this.keyService.makeMasterKey(
|
||||
|
||||
@@ -310,13 +310,16 @@ export class ChangePasswordComponent
|
||||
newMasterKey: MasterKey,
|
||||
newUserKey: [UserKey, EncString],
|
||||
) {
|
||||
const masterKey = await this.keyService.makeMasterKey(
|
||||
this.currentMasterPassword,
|
||||
await firstValueFrom(this.accountService.activeAccount$.pipe(map((a) => a?.email))),
|
||||
await this.kdfConfigService.getKdfConfig(),
|
||||
const [userId, email] = await firstValueFrom(
|
||||
this.accountService.activeAccount$.pipe(map((a) => [a?.id, a?.email])),
|
||||
);
|
||||
|
||||
const masterKey = await this.keyService.makeMasterKey(
|
||||
this.currentMasterPassword,
|
||||
email,
|
||||
await this.kdfConfigService.getKdfConfig(userId),
|
||||
);
|
||||
|
||||
const userId = await firstValueFrom(getUserId(this.accountService.activeAccount$));
|
||||
const newLocalKeyHash = await this.keyService.hashMasterKey(
|
||||
this.masterPassword,
|
||||
newMasterKey,
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
// @ts-strict-ignore
|
||||
import { Component, OnDestroy, OnInit } from "@angular/core";
|
||||
import { FormBuilder, FormControl, ValidatorFn, Validators } from "@angular/forms";
|
||||
import { Subject, takeUntil } from "rxjs";
|
||||
import { Subject, firstValueFrom, takeUntil } from "rxjs";
|
||||
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { DialogService } from "@bitwarden/components";
|
||||
import {
|
||||
KdfConfigService,
|
||||
@@ -43,6 +45,7 @@ export class ChangeKdfComponent implements OnInit, OnDestroy {
|
||||
constructor(
|
||||
private dialogService: DialogService,
|
||||
private kdfConfigService: KdfConfigService,
|
||||
private accountService: AccountService,
|
||||
private formBuilder: FormBuilder,
|
||||
) {
|
||||
this.kdfOptions = [
|
||||
@@ -52,7 +55,8 @@ export class ChangeKdfComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
this.kdfConfig = await this.kdfConfigService.getKdfConfig();
|
||||
const userId = await firstValueFrom(getUserId(this.accountService.activeAccount$));
|
||||
this.kdfConfig = await this.kdfConfigService.getKdfConfig(userId);
|
||||
this.formGroup.get("kdf").setValue(this.kdfConfig.kdfType);
|
||||
this.setFormControlValues(this.kdfConfig);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user