1
0
mirror of https://github.com/bitwarden/browser synced 2026-01-26 14:23:46 +00:00

wip - added milestone 3 FF

This commit is contained in:
Isaac Ivins
2026-01-21 16:37:14 -05:00
parent 2ce35fee99
commit 093091a74b
3 changed files with 63 additions and 18 deletions

View File

@@ -6,14 +6,22 @@
<bit-callout type="warning" title="{{ 'warning' | i18n }}">
{{ "deleteAccountWarning" | i18n }}
</bit-callout>
<!-- Temporary border styles. TODO: Remove when app-user-verification is migrated to the CL. -->
<div class="tw-mb-2 tw-rounded tw-border tw-border-solid tw-border-info-600/25">
<app-user-verification
ngDefaultControl
@if (migrationMilestone3) {
<app-user-verification-form-input
formControlName="verification"
name="verification"
></app-user-verification>
</div>
verificationType="server"
[invalidSecret]="invalidSecret"
></app-user-verification-form-input>
} @else {
<!-- Temporary border styles. TODO: Remove when app-user-verification is migrated to the CL. -->
<div class="tw-mb-2 tw-rounded tw-border tw-border-solid tw-border-info-600/25">
<app-user-verification
ngDefaultControl
formControlName="verification"
name="verification"
></app-user-verification>
</div>
}
<div id="confirmIdentityHelp">
<p>{{ "confirmIdentity" | i18n }}</p>
</div>

View File

@@ -1,13 +1,15 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { Component } from "@angular/core";
import { Component, OnInit } from "@angular/core";
import { FormBuilder, ReactiveFormsModule } from "@angular/forms";
import { JslibModule } from "@bitwarden/angular/jslib.module";
import { UserVerificationFormInputComponent } from "@bitwarden/auth/angular";
import { AccountApiService } from "@bitwarden/common/auth/abstractions/account-api.service";
import { VerificationWithSecret } from "@bitwarden/common/auth/types/verification";
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import {
DialogRef,
AsyncActionsModule,
@@ -27,6 +29,7 @@ import { UserVerificationComponent } from "../app/components/user-verification.c
templateUrl: "delete-account.component.html",
imports: [
JslibModule,
UserVerificationFormInputComponent,
UserVerificationComponent,
ButtonModule,
CalloutModule,
@@ -35,19 +38,36 @@ import { UserVerificationComponent } from "../app/components/user-verification.c
ReactiveFormsModule,
],
})
export class DeleteAccountComponent {
export class DeleteAccountComponent implements OnInit {
deleteForm = this.formBuilder.group({
verification: undefined as VerificationWithSecret | undefined,
});
/**
* Tracks whether the verification failed due to invalid credentials.
* Used to show inline error messages in the verification component.
*/
protected invalidSecret = false;
/**
* Feature flag for UI Migration Milestone 3
*/
protected migrationMilestone3 = false;
constructor(
private i18nService: I18nService,
private platformUtilsService: PlatformUtilsService,
private formBuilder: FormBuilder,
private accountApiService: AccountApiService,
private toastService: ToastService,
private configService: ConfigService,
) {}
async ngOnInit() {
this.migrationMilestone3 = await this.configService.getFeatureFlag(
FeatureFlag.DesktopUiMigrationMilestone3,
);
}
static open(dialogService: DialogService): DialogRef<DeleteAccountComponent> {
return dialogService.open(DeleteAccountComponent);
}
@@ -57,12 +77,21 @@ export class DeleteAccountComponent {
}
submit = async () => {
const verification = this.deleteForm.get("verification").value;
await this.accountApiService.deleteAccount(verification);
this.toastService.showToast({
variant: "success",
title: this.i18nService.t("accountDeleted"),
message: this.i18nService.t("accountDeletedDesc"),
});
try {
if (this.migrationMilestone3) {
this.invalidSecret = false; // Reset error state before attempting
}
const verification = this.deleteForm.get("verification").value;
await this.accountApiService.deleteAccount(verification);
this.toastService.showToast({
variant: "success",
title: this.i18nService.t("accountDeleted"),
message: this.i18nService.t("accountDeletedDesc"),
});
} catch {
if (this.migrationMilestone3) {
this.invalidSecret = true;
}
}
};
}

View File

@@ -76,6 +76,7 @@ export enum FeatureFlag {
/* Desktop */
DesktopUiMigrationMilestone1 = "desktop-ui-migration-milestone-1",
DesktopUiMigrationMilestone3 = "desktop-ui-migration-milestone-3",
/* UIF */
RouterFocusManagement = "router-focus-management",
@@ -164,6 +165,7 @@ export const DefaultFeatureFlagValue = {
/* Desktop */
[FeatureFlag.DesktopUiMigrationMilestone1]: FALSE,
[FeatureFlag.DesktopUiMigrationMilestone3]: FALSE,
/* UIF */
[FeatureFlag.RouterFocusManagement]: FALSE,
@@ -180,6 +182,12 @@ export function getFeatureFlagValue<Flag extends FeatureFlag>(
serverConfig: ServerConfig | null,
flag: Flag,
) {
if (flag === FeatureFlag.DesktopUiMigrationMilestone1) {
return true;
}
if (flag === FeatureFlag.DesktopUiMigrationMilestone3) {
return true;
}
if (serverConfig?.featureStates == null || serverConfig.featureStates[flag] == null) {
return DefaultFeatureFlagValue[flag];
}