1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-16 00:03:56 +00:00

[PM-6727] Part 1: pass userId in login strategies (#9030)

* add validation to initAccount

* pass userId to setMasterKey

* fix key connector tests
This commit is contained in:
Jake Fink
2024-05-03 11:54:29 -04:00
committed by GitHub
parent debfe914c2
commit 69ed6ce1f5
16 changed files with 101 additions and 65 deletions

View File

@@ -1,8 +1,9 @@
import { Organization } from "../../admin-console/models/domain/organization";
import { UserId } from "../../types/guid";
import { IdentityTokenResponse } from "../models/response/identity-token.response";
export abstract class KeyConnectorService {
setMasterKeyFromUrl: (url?: string) => Promise<void>;
setMasterKeyFromUrl: (url: string, userId: UserId) => Promise<void>;
getManagingOrganization: () => Promise<Organization>;
getUsesKeyConnector: () => Promise<boolean>;
migrateUser: () => Promise<void>;
@@ -10,6 +11,7 @@ export abstract class KeyConnectorService {
convertNewSsoUserToKeyConnector: (
tokenResponse: IdentityTokenResponse,
orgId: string,
userId: UserId,
) => Promise<void>;
setUsesKeyConnector: (enabled: boolean) => Promise<void>;
setConvertAccountRequired: (status: boolean) => Promise<void>;

View File

@@ -1,9 +1,11 @@
import { Utils } from "../../../platform/misc/utils";
import { UserId } from "../../../types/guid";
import { TwoFactorProviderType } from "../../enums/two-factor-provider-type";
import { ForceSetPasswordReason } from "./force-set-password-reason";
export class AuthResult {
userId: UserId;
captchaSiteKey = "";
// TODO: PM-3287 - Remove this after 3 releases of backwards compatibility. - Target release 2023.12 for removal
/**

View File

@@ -215,7 +215,7 @@ describe("KeyConnectorService", () => {
const masterKey = new SymmetricCryptoKey(keyArr) as MasterKey;
// Act
await keyConnectorService.setMasterKeyFromUrl(url);
await keyConnectorService.setMasterKeyFromUrl(url, mockUserId);
// Assert
expect(apiService.getMasterKeyFromKeyConnector).toHaveBeenCalledWith(url);
@@ -235,7 +235,7 @@ describe("KeyConnectorService", () => {
try {
// Act
await keyConnectorService.setMasterKeyFromUrl(url);
await keyConnectorService.setMasterKeyFromUrl(url, mockUserId);
} catch {
// Assert
expect(logService.error).toHaveBeenCalledWith(error);

View File

@@ -16,6 +16,7 @@ import {
StateProvider,
UserKeyDefinition,
} from "../../platform/state";
import { UserId } from "../../types/guid";
import { MasterKey } from "../../types/key";
import { AccountService } from "../abstractions/account.service";
import { KeyConnectorService as KeyConnectorServiceAbstraction } from "../abstractions/key-connector.service";
@@ -100,12 +101,11 @@ export class KeyConnectorService implements KeyConnectorServiceAbstraction {
}
// TODO: UserKey should be renamed to MasterKey and typed accordingly
async setMasterKeyFromUrl(url: string) {
async setMasterKeyFromUrl(url: string, userId: UserId) {
try {
const masterKeyResponse = await this.apiService.getMasterKeyFromKeyConnector(url);
const keyArr = Utils.fromB64ToArray(masterKeyResponse.key);
const masterKey = new SymmetricCryptoKey(keyArr) as MasterKey;
const userId = (await firstValueFrom(this.accountService.activeAccount$))?.id;
await this.masterPasswordService.setMasterKey(masterKey, userId);
} catch (e) {
this.handleKeyConnectorError(e);
@@ -123,7 +123,11 @@ export class KeyConnectorService implements KeyConnectorServiceAbstraction {
);
}
async convertNewSsoUserToKeyConnector(tokenResponse: IdentityTokenResponse, orgId: string) {
async convertNewSsoUserToKeyConnector(
tokenResponse: IdentityTokenResponse,
orgId: string,
userId: UserId,
) {
// TODO: Remove after tokenResponse.keyConnectorUrl is deprecated in 2023.10 release (https://bitwarden.atlassian.net/browse/PM-3537)
const {
kdf,
@@ -145,12 +149,11 @@ export class KeyConnectorService implements KeyConnectorServiceAbstraction {
kdfConfig,
);
const keyConnectorRequest = new KeyConnectorUserKeyRequest(masterKey.encKeyB64);
const userId = (await firstValueFrom(this.accountService.activeAccount$))?.id;
await this.masterPasswordService.setMasterKey(masterKey, userId);
const userKey = await this.cryptoService.makeUserKey(masterKey);
await this.cryptoService.setUserKey(userKey[0]);
await this.cryptoService.setMasterKeyEncryptedUserKey(userKey[1].encryptedString);
await this.cryptoService.setUserKey(userKey[0], userId);
await this.cryptoService.setMasterKeyEncryptedUserKey(userKey[1].encryptedString, userId);
const [pubKey, privKey] = await this.cryptoService.makeKeyPair();

View File

@@ -771,6 +771,19 @@ export class CryptoService implements CryptoServiceAbstraction {
publicKey: string;
privateKey: EncString;
}> {
// Verify keys don't exist
const existingUserKey = await this.getUserKey();
const existingPrivateKey = await this.getPrivateKey();
if (existingUserKey != null || existingPrivateKey != null) {
if (existingUserKey != null) {
this.logService.error("Tried to initialize account with existing user key.");
}
if (existingPrivateKey != null) {
this.logService.error("Tried to initialize account with existing private key.");
}
throw new Error("Cannot initialize account, keys already exist.");
}
const userKey = (await this.keyGenerationService.createKey(512)) as UserKey;
const [publicKey, privateKey] = await this.makeKeyPair(userKey);
await this.setUserKey(userKey);