1
0
mirror of https://github.com/bitwarden/browser.git synced 2025-01-06 18:57:56 +01:00

PM-1049 - Update all User Decryption Options response and state models in light of the back end changes from a list to an object. Web building now with decryption options stored on state under the account successfully. Must now build out state service methods for retrieving / setting account decryption options for use elsewhere.

This commit is contained in:
Jared Snider 2023-06-06 18:19:02 -04:00
parent e1b997eec7
commit 763a0d6963
No known key found for this signature in database
GPG Key ID: A149DDD612516286
16 changed files with 81 additions and 162 deletions

View File

@ -1,5 +0,0 @@
export enum UserDecryptionOption {
MASTER_PASSWORD = "masterPasswordOption",
TRUSTED_DEVICE = "trustedDeviceOption",
KEY_CONNECTOR = "keyConnectorOption",
}

View File

@ -5,7 +5,12 @@ import { LogService } from "../../abstractions/log.service";
import { MessagingService } from "../../abstractions/messaging.service";
import { PlatformUtilsService } from "../../abstractions/platformUtils.service";
import { StateService } from "../../abstractions/state.service";
import { Account, AccountProfile, AccountTokens } from "../../models/domain/account";
import {
Account,
AccountDecryptionOptions,
AccountProfile,
AccountTokens,
} from "../../models/domain/account";
import { KeysRequest } from "../../models/request/keys.request";
import { TokenService } from "../abstractions/token.service";
import { TwoFactorService } from "../abstractions/two-factor.service";
@ -102,8 +107,6 @@ export abstract class LogInStrategy {
protected async saveAccountInformation(tokenResponse: IdentityTokenResponse) {
const accountInformation = await this.tokenService.decodeToken(tokenResponse.accessToken);
// TODO: add AccountDecryptionOptions to the account
await this.stateService.addAccount(
new Account({
profile: {
@ -126,6 +129,9 @@ export abstract class LogInStrategy {
refreshToken: tokenResponse.refreshToken,
},
},
decryptionOptions: AccountDecryptionOptions.fromResponse(
tokenResponse.userDecryptionOptions
),
})
);
}

View File

@ -1,11 +0,0 @@
import { Jsonify } from "type-fest";
import { UserDecryptionOptionBase } from "./user-decryption-options-base.model";
export class KeyConnectorUserDecryptionOption extends UserDecryptionOptionBase {
keyConnectorUrl: string;
constructor(data: Jsonify<KeyConnectorUserDecryptionOption>) {
super(data.enabled);
this.keyConnectorUrl = data.keyConnectorUrl;
}
}

View File

@ -1,7 +0,0 @@
import { UserDecryptionOptionBase } from "./user-decryption-options-base.model";
export class MasterPasswordUserDecryptionOption extends UserDecryptionOptionBase {
constructor(enabled: boolean) {
super(enabled);
}
}

View File

@ -1,11 +0,0 @@
import { Jsonify } from "type-fest";
import { UserDecryptionOptionBase } from "./user-decryption-options-base.model";
export class TrustedDeviceUserDecryptionOption extends UserDecryptionOptionBase {
hasAdminApproval: boolean;
constructor(data: Jsonify<TrustedDeviceUserDecryptionOption>) {
super(data.enabled);
this.hasAdminApproval = data.hasAdminApproval;
}
}

View File

@ -1,6 +0,0 @@
export class UserDecryptionOptionBase {
enabled: boolean;
constructor(enabled: boolean) {
this.enabled = enabled;
}
}

View File

@ -1,13 +1,8 @@
import { KdfType } from "../../../enums";
import { BaseResponse } from "../../../models/response/base.response";
import { UserDecryptionOption } from "../../enums/user-decryption-option.enum";
import { UserDecryptionOptionResponseType } from "../../types/user-decryption-option-response";
import { KeyConnectorDecryptionOptionResponse } from "./key-connector-decryption-option.response";
import { MasterPasswordDecryptionOptionResponse } from "./master-password-decryption-option.response";
import { MasterPasswordPolicyResponse } from "./master-password-policy.response";
import { TrustedDeviceDecryptionOptionResponse } from "./trusted-device-decryption-option.response";
import { UserDecryptionOptionResponse } from "./user-decryption-option.response";
import { UserDecryptionOptionsResponse } from "./user-decryption-options/user-decryption-options.response";
export class IdentityTokenResponse extends BaseResponse {
accessToken: string;
@ -28,7 +23,7 @@ export class IdentityTokenResponse extends BaseResponse {
apiUseKeyConnector: boolean;
keyConnectorUrl: string;
userDecryptionOptions: Array<UserDecryptionOptionResponseType>;
userDecryptionOptions: UserDecryptionOptionsResponse;
constructor(response: any) {
super(response);
@ -52,26 +47,8 @@ export class IdentityTokenResponse extends BaseResponse {
this.getResponseProperty("MasterPasswordPolicy")
);
const serverUserDecryptionOptions = this.getResponseProperty("UserDecryptionOptions");
if (serverUserDecryptionOptions) {
this.userDecryptionOptions = serverUserDecryptionOptions.map(
(serverUserDecryptionOption: any) => {
const response = new UserDecryptionOptionResponse(serverUserDecryptionOption);
switch (response.object) {
case UserDecryptionOption.MASTER_PASSWORD: {
return new MasterPasswordDecryptionOptionResponse(serverUserDecryptionOption);
}
case UserDecryptionOption.TRUSTED_DEVICE: {
return new TrustedDeviceDecryptionOptionResponse(serverUserDecryptionOption);
}
case UserDecryptionOption.KEY_CONNECTOR: {
return new KeyConnectorDecryptionOptionResponse(serverUserDecryptionOption);
}
}
}
);
}
this.userDecryptionOptions = new UserDecryptionOptionsResponse(
this.getResponseProperty("UserDecryptionOptions")
);
}
}

View File

@ -1,10 +0,0 @@
import { UserDecryptionOptionResponse } from "./user-decryption-option.response";
export class KeyConnectorDecryptionOptionResponse extends UserDecryptionOptionResponse {
keyConnectorUrl: string;
constructor(response: any) {
super(response);
this.keyConnectorUrl = this.getResponseProperty("KeyConnectorUrl");
}
}

View File

@ -1,7 +0,0 @@
import { UserDecryptionOptionResponse } from "./user-decryption-option.response";
export class MasterPasswordDecryptionOptionResponse extends UserDecryptionOptionResponse {
constructor(response: any) {
super(response);
}
}

View File

@ -1,10 +0,0 @@
import { UserDecryptionOptionResponse } from "./user-decryption-option.response";
export class TrustedDeviceDecryptionOptionResponse extends UserDecryptionOptionResponse {
hasAdminApproval: boolean;
constructor(response: any) {
super(response);
this.hasAdminApproval = this.getResponseProperty("HasAdminApproval");
}
}

View File

@ -1,11 +0,0 @@
import { BaseResponse } from "../../../models/response/base.response";
export class UserDecryptionOptionResponse extends BaseResponse {
object: string;
constructor(response: any) {
super(response);
this.object = this.getResponseProperty("Object");
}
}

View File

@ -0,0 +1,10 @@
import { BaseResponse } from "../../../../models/response/base.response";
export class KeyConnectorUserDecryptionOptionResponse extends BaseResponse {
keyConnectorUrl: string;
constructor(response: any) {
super(response);
this.keyConnectorUrl = this.getResponseProperty("KeyConnectorUrl");
}
}

View File

@ -0,0 +1,10 @@
import { BaseResponse } from "../../../../models/response/base.response";
export class TrustedDeviceUserDecryptionOptionResponse extends BaseResponse {
hasAdminApproval: boolean;
constructor(response: any) {
super(response);
this.hasAdminApproval = this.getResponseProperty("HasAdminApproval");
}
}

View File

@ -0,0 +1,27 @@
import { BaseResponse } from "../../../../models/response/base.response";
import { KeyConnectorUserDecryptionOptionResponse } from "./key-connector-user-decryption-option.response";
import { TrustedDeviceUserDecryptionOptionResponse } from "./trusted-device-user-decryption-option.response";
export class UserDecryptionOptionsResponse extends BaseResponse {
hasMasterPassword: boolean;
trustedDeviceOption?: TrustedDeviceUserDecryptionOptionResponse;
keyConnectorOption?: KeyConnectorUserDecryptionOptionResponse;
constructor(response: any) {
super(response);
this.hasMasterPassword = this.getResponseProperty("HasMasterPassword");
if (response.TrustedDeviceOption) {
this.trustedDeviceOption = new TrustedDeviceUserDecryptionOptionResponse(
this.getResponseProperty("TrustedDeviceOption")
);
}
if (response.KeyConnectorOption) {
this.keyConnectorOption = new KeyConnectorUserDecryptionOptionResponse(
this.getResponseProperty("KeyConnectorOption")
);
}
}
}

View File

@ -1,8 +0,0 @@
import { KeyConnectorDecryptionOptionResponse } from "../models/response/key-connector-decryption-option.response";
import { MasterPasswordDecryptionOptionResponse } from "../models/response/master-password-decryption-option.response";
import { TrustedDeviceDecryptionOptionResponse } from "../models/response/trusted-device-decryption-option.response";
export type UserDecryptionOptionResponseType =
| MasterPasswordDecryptionOptionResponse
| TrustedDeviceDecryptionOptionResponse
| KeyConnectorDecryptionOptionResponse;

View File

@ -8,15 +8,11 @@ import { ProviderData } from "../../admin-console/models/data/provider.data";
import { Policy } from "../../admin-console/models/domain/policy";
import { CollectionView } from "../../admin-console/models/view/collection.view";
import { AuthenticationStatus } from "../../auth/enums/authentication-status";
import { UserDecryptionOption } from "../../auth/enums/user-decryption-option.enum";
import { EnvironmentUrls } from "../../auth/models/domain/environment-urls";
import { ForceResetPasswordReason } from "../../auth/models/domain/force-reset-password-reason";
import { KeyConnectorUserDecryptionOption } from "../../auth/models/domain/user-decryption-options/key-connector-user-decryption-option.model";
import { MasterPasswordUserDecryptionOption } from "../../auth/models/domain/user-decryption-options/master-password-user-decryption-option.model";
import { TrustedDeviceUserDecryptionOption } from "../../auth/models/domain/user-decryption-options/trusted-device-user-decryption-option.model";
import { KeyConnectorDecryptionOptionResponse } from "../../auth/models/response/key-connector-decryption-option.response";
import { TrustedDeviceDecryptionOptionResponse } from "../../auth/models/response/trusted-device-decryption-option.response";
import { UserDecryptionOptionResponseType } from "../../auth/types/user-decryption-option-response";
import { KeyConnectorUserDecryptionOptionResponse } from "../../auth/models/response/user-decryption-options/key-connector-user-decryption-option.response";
import { TrustedDeviceUserDecryptionOptionResponse } from "../../auth/models/response/user-decryption-options/trusted-device-user-decryption-option.response";
import { UserDecryptionOptionsResponse } from "../../auth/models/response/user-decryption-options/user-decryption-options.response";
import { KdfType, UriMatchType } from "../../enums";
import { Utils } from "../../misc/utils";
import { GeneratedPasswordHistory } from "../../tools/generator/password";
@ -277,9 +273,9 @@ export class AccountTokens {
}
export class AccountDecryptionOptions {
[UserDecryptionOption.MASTER_PASSWORD]?: MasterPasswordUserDecryptionOption;
[UserDecryptionOption.TRUSTED_DEVICE]?: TrustedDeviceUserDecryptionOption;
[UserDecryptionOption.KEY_CONNECTOR]?: KeyConnectorUserDecryptionOption;
hasMasterPassword: boolean;
trustedDeviceOption?: TrustedDeviceUserDecryptionOptionResponse;
keyConnectorOption?: KeyConnectorUserDecryptionOptionResponse;
constructor(init?: Partial<AccountDecryptionOptions>) {
if (init) {
@ -287,42 +283,21 @@ export class AccountDecryptionOptions {
}
}
static fromIdTokenResponse(
// serverUserDecryptionOptions: Array<{ Object: string; [key: string]: any }>
userDecryptionOptionResponse: Array<UserDecryptionOptionResponseType>
) {
const accountDecryptionOptions = new AccountDecryptionOptions();
// Convert UserDecryptionOptions array to dictionary
for (const optionResponse of userDecryptionOptionResponse) {
const type = optionResponse.object as UserDecryptionOption;
switch (type) {
case UserDecryptionOption.MASTER_PASSWORD:
accountDecryptionOptions[UserDecryptionOption.MASTER_PASSWORD] =
new MasterPasswordUserDecryptionOption(true);
break;
case UserDecryptionOption.TRUSTED_DEVICE:
accountDecryptionOptions[UserDecryptionOption.TRUSTED_DEVICE] =
new TrustedDeviceUserDecryptionOption({
enabled: true,
hasAdminApproval: (optionResponse as TrustedDeviceDecryptionOptionResponse)
.hasAdminApproval,
});
break;
case UserDecryptionOption.KEY_CONNECTOR:
accountDecryptionOptions[UserDecryptionOption.KEY_CONNECTOR] =
new KeyConnectorUserDecryptionOption({
enabled: true,
keyConnectorUrl: (optionResponse as KeyConnectorDecryptionOptionResponse)
.keyConnectorUrl,
});
break;
default:
continue;
}
static fromResponse(response: UserDecryptionOptionsResponse): AccountDecryptionOptions {
if (response == null) {
return null;
}
const accountDecryptionOptions = new AccountDecryptionOptions();
accountDecryptionOptions.hasMasterPassword = response.hasMasterPassword;
if (response.trustedDeviceOption) {
accountDecryptionOptions.trustedDeviceOption = response.trustedDeviceOption;
}
if (response.keyConnectorOption) {
accountDecryptionOptions.keyConnectorOption = response.keyConnectorOption;
}
return accountDecryptionOptions;
}
static fromJSON(obj: Jsonify<AccountDecryptionOptions>): AccountDecryptionOptions {