mirror of
https://github.com/bitwarden/browser
synced 2025-12-17 16:53:34 +00:00
[PM-14613] Remove account deprovisioning feature flag (#14353)
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
<span bitDialogTitle>
|
||||
<span *ngIf="!data.orgDomain">{{ "newDomain" | i18n }}</span>
|
||||
<span *ngIf="data.orgDomain">
|
||||
{{ ((accountDeprovisioningEnabled$ | async) ? "claimDomain" : "verifyDomain") | i18n }}
|
||||
{{ "claimDomain" | i18n }}
|
||||
</span>
|
||||
|
||||
<span *ngIf="data.orgDomain" class="tw-text-xs tw-text-muted">
|
||||
@@ -15,30 +15,17 @@
|
||||
</span>
|
||||
|
||||
<span *ngIf="data?.orgDomain && !data.orgDomain?.verifiedDate" bitBadge variant="warning">
|
||||
{{
|
||||
((accountDeprovisioningEnabled$ | async)
|
||||
? "domainStatusUnderVerification"
|
||||
: "domainStatusUnverified"
|
||||
) | i18n
|
||||
}}
|
||||
{{ "domainStatusUnderVerification" | i18n }}
|
||||
</span>
|
||||
<span *ngIf="data?.orgDomain && data?.orgDomain?.verifiedDate" bitBadge variant="success">
|
||||
{{
|
||||
((accountDeprovisioningEnabled$ | async) ? "domainStatusClaimed" : "domainStatusVerified")
|
||||
| i18n
|
||||
}}
|
||||
{{ "domainStatusClaimed" | i18n }}
|
||||
</span>
|
||||
</span>
|
||||
<div bitDialogContent>
|
||||
<bit-form-field>
|
||||
<bit-label>{{ "domainName" | i18n }}</bit-label>
|
||||
<input bitInput appAutofocus formControlName="domainName" [showErrorsWhenDisabled]="true" />
|
||||
<bit-hint>{{
|
||||
((accountDeprovisioningEnabled$ | async)
|
||||
? "claimDomainNameInputHint"
|
||||
: "domainNameInputHint"
|
||||
) | i18n
|
||||
}}</bit-hint>
|
||||
<bit-hint>{{ "claimDomainNameInputHint" | i18n }}</bit-hint>
|
||||
</bit-form-field>
|
||||
|
||||
<bit-form-field *ngIf="data?.orgDomain">
|
||||
@@ -57,29 +44,18 @@
|
||||
<bit-callout
|
||||
*ngIf="data?.orgDomain && !data?.orgDomain?.verifiedDate"
|
||||
type="info"
|
||||
title="{{
|
||||
(accountDeprovisioningEnabled$ | async)
|
||||
? ('automaticClaimedDomains' | i18n | uppercase)
|
||||
: ('automaticDomainVerification' | i18n)
|
||||
}}"
|
||||
title="{{ 'automaticClaimedDomains' | i18n | uppercase }}"
|
||||
>
|
||||
{{
|
||||
((accountDeprovisioningEnabled$ | async)
|
||||
? "automaticDomainClaimProcess"
|
||||
: "automaticDomainVerificationProcess"
|
||||
) | i18n
|
||||
}}
|
||||
{{ "automaticDomainClaimProcess" | i18n }}
|
||||
</bit-callout>
|
||||
</div>
|
||||
<ng-container bitDialogFooter>
|
||||
<button type="submit" bitButton bitFormButton buttonType="primary">
|
||||
<span *ngIf="!data?.orgDomain">{{ "next" | i18n }}</span>
|
||||
<span *ngIf="data?.orgDomain && !data?.orgDomain?.verifiedDate">{{
|
||||
((accountDeprovisioningEnabled$ | async) ? "claimDomain" : "verifyDomain") | i18n
|
||||
}}</span>
|
||||
<span *ngIf="data?.orgDomain?.verifiedDate">{{
|
||||
((accountDeprovisioningEnabled$ | async) ? "reclaimDomain" : "reverifyDomain") | i18n
|
||||
"claimDomain" | i18n
|
||||
}}</span>
|
||||
<span *ngIf="data?.orgDomain?.verifiedDate">{{ "reclaimDomain" | i18n }}</span>
|
||||
</button>
|
||||
<button bitButton buttonType="secondary" (click)="dialogRef.close()" type="button">
|
||||
{{ "cancel" | i18n }}
|
||||
|
||||
@@ -2,19 +2,15 @@
|
||||
// @ts-strict-ignore
|
||||
import { Component, Inject, OnDestroy, OnInit } from "@angular/core";
|
||||
import { FormBuilder, FormControl, FormGroup, ValidatorFn, Validators } from "@angular/forms";
|
||||
import { Subject, takeUntil, Observable, firstValueFrom } from "rxjs";
|
||||
import { Subject, takeUntil } from "rxjs";
|
||||
|
||||
import { OrgDomainApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization-domain/org-domain-api.service.abstraction";
|
||||
import { OrgDomainServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization-domain/org-domain.service.abstraction";
|
||||
import { OrganizationDomainResponse } from "@bitwarden/common/admin-console/abstractions/organization-domain/responses/organization-domain.response";
|
||||
import { OrganizationDomainRequest } from "@bitwarden/common/admin-console/services/organization-domain/requests/organization-domain.request";
|
||||
import { HttpStatusCode } from "@bitwarden/common/enums";
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { CryptoFunctionService as CryptoFunctionServiceAbstraction } from "@bitwarden/common/key-management/crypto/abstractions/crypto-function.service";
|
||||
import { ErrorResponse } from "@bitwarden/common/models/response/error.response";
|
||||
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 { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service";
|
||||
import { DialogRef, DIALOG_DATA, DialogService, ToastService } from "@bitwarden/components";
|
||||
|
||||
@@ -32,7 +28,6 @@ export interface DomainAddEditDialogData {
|
||||
export class DomainAddEditDialogComponent implements OnInit, OnDestroy {
|
||||
private componentDestroyed$: Subject<void> = new Subject();
|
||||
|
||||
accountDeprovisioningEnabled$: Observable<boolean>;
|
||||
domainForm: FormGroup;
|
||||
|
||||
get domainNameCtrl(): FormControl {
|
||||
@@ -50,20 +45,13 @@ export class DomainAddEditDialogComponent implements OnInit, OnDestroy {
|
||||
public dialogRef: DialogRef,
|
||||
@Inject(DIALOG_DATA) public data: DomainAddEditDialogData,
|
||||
private formBuilder: FormBuilder,
|
||||
private cryptoFunctionService: CryptoFunctionServiceAbstraction,
|
||||
private platformUtilsService: PlatformUtilsService,
|
||||
private i18nService: I18nService,
|
||||
private orgDomainApiService: OrgDomainApiServiceAbstraction,
|
||||
private orgDomainService: OrgDomainServiceAbstraction,
|
||||
private validationService: ValidationService,
|
||||
private dialogService: DialogService,
|
||||
private toastService: ToastService,
|
||||
private configService: ConfigService,
|
||||
) {
|
||||
this.accountDeprovisioningEnabled$ = this.configService.getFeatureFlag$(
|
||||
FeatureFlag.AccountDeprovisioning,
|
||||
);
|
||||
}
|
||||
) {}
|
||||
|
||||
// Angular Method Implementations
|
||||
|
||||
@@ -73,11 +61,7 @@ export class DomainAddEditDialogComponent implements OnInit, OnDestroy {
|
||||
"",
|
||||
[
|
||||
Validators.required,
|
||||
domainNameValidator(
|
||||
(await firstValueFrom(this.accountDeprovisioningEnabled$))
|
||||
? this.i18nService.t("invalidDomainNameClaimMessage")
|
||||
: this.i18nService.t("invalidDomainNameMessage"),
|
||||
),
|
||||
domainNameValidator(this.i18nService.t("invalidDomainNameClaimMessage")),
|
||||
uniqueInArrayValidator(
|
||||
this.data.existingDomainNames,
|
||||
this.i18nService.t("duplicateDomainError"),
|
||||
@@ -223,22 +207,13 @@ export class DomainAddEditDialogComponent implements OnInit, OnDestroy {
|
||||
this.toastService.showToast({
|
||||
variant: "success",
|
||||
title: null,
|
||||
message: this.i18nService.t(
|
||||
(await firstValueFrom(this.accountDeprovisioningEnabled$))
|
||||
? "domainClaimed"
|
||||
: "domainVerified",
|
||||
),
|
||||
message: this.i18nService.t("domainClaimed"),
|
||||
});
|
||||
this.dialogRef.close();
|
||||
} else {
|
||||
this.domainNameCtrl.setErrors({
|
||||
errorPassthrough: {
|
||||
message: this.i18nService.t(
|
||||
(await firstValueFrom(this.accountDeprovisioningEnabled$))
|
||||
? "domainNotClaimed"
|
||||
: "domainNotVerified",
|
||||
this.domainNameCtrl.value,
|
||||
),
|
||||
message: this.i18nService.t("domainNotClaimed", this.domainNameCtrl.value),
|
||||
},
|
||||
});
|
||||
// For the case where user opens dialog and reverifies when domain name formControl disabled.
|
||||
|
||||
@@ -4,11 +4,7 @@
|
||||
</button>
|
||||
</app-header>
|
||||
|
||||
<p
|
||||
bitTypography="body1"
|
||||
class="tw-text-main tw-w-2/5"
|
||||
*ngIf="accountDeprovisioningEnabled$ | async"
|
||||
>
|
||||
<p bitTypography="body1" class="tw-text-main tw-w-2/5">
|
||||
{{ "claimedDomainsDesc" | i18n }}
|
||||
<a
|
||||
bitLink
|
||||
@@ -58,16 +54,10 @@
|
||||
</td>
|
||||
<td bitCell>
|
||||
<span *ngIf="!orgDomain?.verifiedDate" bitBadge variant="warning">{{
|
||||
((accountDeprovisioningEnabled$ | async)
|
||||
? "domainStatusUnderVerification"
|
||||
: "domainStatusUnverified"
|
||||
) | i18n
|
||||
"domainStatusUnderVerification" | i18n
|
||||
}}</span>
|
||||
<span *ngIf="orgDomain?.verifiedDate" bitBadge variant="success">{{
|
||||
((accountDeprovisioningEnabled$ | async)
|
||||
? "domainStatusClaimed"
|
||||
: "domainStatusVerified"
|
||||
) | i18n
|
||||
"domainStatusClaimed" | i18n
|
||||
}}</span>
|
||||
</td>
|
||||
<td bitCell class="tw-text-muted">
|
||||
@@ -94,10 +84,7 @@
|
||||
type="button"
|
||||
>
|
||||
<i class="bwi bwi-fw bwi-check" aria-hidden="true"></i>
|
||||
{{
|
||||
((accountDeprovisioningEnabled$ | async) ? "claimDomain" : "verifyDomain")
|
||||
| i18n
|
||||
}}
|
||||
{{ "claimDomain" | i18n }}
|
||||
</button>
|
||||
<button bitMenuItem (click)="deleteDomain(orgDomain.id)" type="button">
|
||||
<span class="tw-text-danger">
|
||||
|
||||
@@ -11,7 +11,6 @@ import {
|
||||
switchMap,
|
||||
take,
|
||||
takeUntil,
|
||||
withLatestFrom,
|
||||
} from "rxjs";
|
||||
|
||||
import { OrgDomainApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization-domain/org-domain-api.service.abstraction";
|
||||
@@ -22,7 +21,6 @@ import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { HttpStatusCode } from "@bitwarden/common/enums";
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { ErrorResponse } from "@bitwarden/common/models/response/error.response";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
@@ -46,7 +44,6 @@ export class DomainVerificationComponent implements OnInit, OnDestroy {
|
||||
|
||||
organizationId: string;
|
||||
orgDomains$: Observable<OrganizationDomainResponse[]>;
|
||||
accountDeprovisioningEnabled$: Observable<boolean>;
|
||||
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
@@ -59,11 +56,7 @@ export class DomainVerificationComponent implements OnInit, OnDestroy {
|
||||
private configService: ConfigService,
|
||||
private policyService: PolicyService,
|
||||
private accountService: AccountService,
|
||||
) {
|
||||
this.accountDeprovisioningEnabled$ = this.configService.getFeatureFlag$(
|
||||
FeatureFlag.AccountDeprovisioning,
|
||||
);
|
||||
}
|
||||
) {}
|
||||
|
||||
async ngOnInit() {
|
||||
this.orgDomains$ = this.orgDomainService.orgDomains$;
|
||||
@@ -85,20 +78,18 @@ export class DomainVerificationComponent implements OnInit, OnDestroy {
|
||||
async load() {
|
||||
await this.orgDomainApiService.getAllByOrgId(this.organizationId);
|
||||
|
||||
if (await this.configService.getFeatureFlag(FeatureFlag.AccountDeprovisioning)) {
|
||||
const singleOrgPolicy = await firstValueFrom(
|
||||
this.accountService.activeAccount$.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) => this.policyService.policies$(userId)),
|
||||
map((policies) =>
|
||||
policies.find(
|
||||
(p) => p.type === PolicyType.SingleOrg && p.organizationId === this.organizationId,
|
||||
),
|
||||
const singleOrgPolicy = await firstValueFrom(
|
||||
this.accountService.activeAccount$.pipe(
|
||||
getUserId,
|
||||
switchMap((userId) => this.policyService.policies$(userId)),
|
||||
map((policies) =>
|
||||
policies.find(
|
||||
(p) => p.type === PolicyType.SingleOrg && p.organizationId === this.organizationId,
|
||||
),
|
||||
),
|
||||
);
|
||||
this.singleOrgPolicyEnabled = singleOrgPolicy?.enabled ?? false;
|
||||
}
|
||||
),
|
||||
);
|
||||
this.singleOrgPolicyEnabled = singleOrgPolicy?.enabled ?? false;
|
||||
|
||||
this.loading = false;
|
||||
}
|
||||
@@ -110,29 +101,30 @@ export class DomainVerificationComponent implements OnInit, OnDestroy {
|
||||
existingDomainNames: this.getExistingDomainNames(),
|
||||
};
|
||||
|
||||
await firstValueFrom(
|
||||
this.configService.getFeatureFlag$(FeatureFlag.AccountDeprovisioning).pipe(
|
||||
withLatestFrom(this.orgDomains$),
|
||||
map(async ([accountDeprovisioningEnabled, organizationDomains]) => {
|
||||
if (
|
||||
accountDeprovisioningEnabled &&
|
||||
const showSingleOrgWarning = await firstValueFrom(
|
||||
this.orgDomains$.pipe(
|
||||
map(
|
||||
(organizationDomains) =>
|
||||
!this.singleOrgPolicyEnabled &&
|
||||
organizationDomains.every((domain) => domain.verifiedDate === null)
|
||||
) {
|
||||
await this.dialogService.openSimpleDialog({
|
||||
title: { key: "claim-domain-single-org-warning" },
|
||||
content: { key: "single-org-revoked-user-warning" },
|
||||
cancelButtonText: { key: "cancel" },
|
||||
acceptButtonText: { key: "confirm" },
|
||||
acceptAction: () => this.openAddDomainDialog(domainAddEditDialogData),
|
||||
type: "info",
|
||||
});
|
||||
} else {
|
||||
await this.openAddDomainDialog(domainAddEditDialogData);
|
||||
}
|
||||
}),
|
||||
organizationDomains.every((domain) => domain.verifiedDate === null),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
if (showSingleOrgWarning) {
|
||||
await this.dialogService.openSimpleDialog({
|
||||
title: { key: "claim-domain-single-org-warning" },
|
||||
content: { key: "single-org-revoked-user-warning" },
|
||||
cancelButtonText: { key: "cancel" },
|
||||
acceptButtonText: { key: "confirm" },
|
||||
acceptAction: () => this.openAddDomainDialog(domainAddEditDialogData),
|
||||
type: "info",
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
await this.openAddDomainDialog(domainAddEditDialogData);
|
||||
}
|
||||
|
||||
private async openAddDomainDialog(domainAddEditDialogData: DomainAddEditDialogData) {
|
||||
@@ -184,22 +176,13 @@ export class DomainVerificationComponent implements OnInit, OnDestroy {
|
||||
this.toastService.showToast({
|
||||
variant: "success",
|
||||
title: null,
|
||||
message: this.i18nService.t(
|
||||
(await firstValueFrom(this.accountDeprovisioningEnabled$))
|
||||
? "domainClaimed"
|
||||
: "domainVerified",
|
||||
),
|
||||
message: this.i18nService.t("domainClaimed"),
|
||||
});
|
||||
} else {
|
||||
this.toastService.showToast({
|
||||
variant: "error",
|
||||
title: null,
|
||||
message: this.i18nService.t(
|
||||
(await firstValueFrom(this.accountDeprovisioningEnabled$))
|
||||
? "domainNotClaimed"
|
||||
: "domainNotVerified",
|
||||
domainName,
|
||||
),
|
||||
message: this.i18nService.t("domainNotClaimed", domainName),
|
||||
});
|
||||
// Update this item so the last checked date gets updated.
|
||||
await this.updateOrgDomain(orgDomainId);
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
import { inject, NgModule } from "@angular/core";
|
||||
import { NgModule } from "@angular/core";
|
||||
import { RouterModule, Routes } from "@angular/router";
|
||||
|
||||
import { authGuard } from "@bitwarden/angular/auth/guards";
|
||||
import { canAccessSettingsTab } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { isEnterpriseOrgGuard } from "@bitwarden/web-vault/app/admin-console/organizations/guards/is-enterprise-org.guard";
|
||||
import { organizationPermissionsGuard } from "@bitwarden/web-vault/app/admin-console/organizations/guards/org-permissions.guard";
|
||||
import { OrganizationLayoutComponent } from "@bitwarden/web-vault/app/admin-console/organizations/layouts/organization-layout.component";
|
||||
@@ -30,12 +28,7 @@ const routes: Routes = [
|
||||
component: DomainVerificationComponent,
|
||||
canActivate: [organizationPermissionsGuard((org) => org.canManageDomainVerification)],
|
||||
resolve: {
|
||||
titleId: async () => {
|
||||
const configService = inject(ConfigService);
|
||||
return (await configService.getFeatureFlag(FeatureFlag.AccountDeprovisioning))
|
||||
? "claimedDomains"
|
||||
: "domainVerification";
|
||||
},
|
||||
titleId: "claimedDomains",
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -31,10 +31,7 @@
|
||||
<input bitInput type="text" formControlName="ssoIdentifier" />
|
||||
<bit-hint>
|
||||
{{ "ssoIdentifierHintPartOne" | i18n }}
|
||||
<a bitLink routerLink="../domain-verification">{{
|
||||
((accountDeprovisioningEnabled$ | async) ? "claimedDomains" : "domainVerification")
|
||||
| i18n
|
||||
}}</a>
|
||||
<a bitLink routerLink="../domain-verification">{{ "claimedDomains" | i18n }}</a>
|
||||
</bit-hint>
|
||||
</bit-form-field>
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
Validators,
|
||||
} from "@angular/forms";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
import { concatMap, firstValueFrom, Observable, Subject, takeUntil } from "rxjs";
|
||||
import { concatMap, firstValueFrom, Subject, takeUntil } from "rxjs";
|
||||
|
||||
import { ControlsOf } from "@bitwarden/angular/types/controls-of";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
@@ -33,8 +33,6 @@ import { OrganizationSsoRequest } from "@bitwarden/common/auth/models/request/or
|
||||
import { OrganizationSsoResponse } from "@bitwarden/common/auth/models/response/organization-sso.response";
|
||||
import { SsoConfigView } from "@bitwarden/common/auth/models/view/sso-config.view";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
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 { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
@@ -191,8 +189,6 @@ export class SsoComponent implements OnInit, OnDestroy {
|
||||
return this.ssoConfigForm?.controls?.configType as FormControl;
|
||||
}
|
||||
|
||||
accountDeprovisioningEnabled$: Observable<boolean>;
|
||||
|
||||
constructor(
|
||||
private formBuilder: FormBuilder,
|
||||
private route: ActivatedRoute,
|
||||
@@ -202,13 +198,8 @@ export class SsoComponent implements OnInit, OnDestroy {
|
||||
private organizationService: OrganizationService,
|
||||
private accountService: AccountService,
|
||||
private organizationApiService: OrganizationApiServiceAbstraction,
|
||||
private configService: ConfigService,
|
||||
private toastService: ToastService,
|
||||
) {
|
||||
this.accountDeprovisioningEnabled$ = this.configService.getFeatureFlag$(
|
||||
FeatureFlag.AccountDeprovisioning,
|
||||
);
|
||||
}
|
||||
) {}
|
||||
|
||||
async ngOnInit() {
|
||||
this.enabledCtrl.valueChanges.pipe(takeUntil(this.destroy$)).subscribe((enabled) => {
|
||||
|
||||
Reference in New Issue
Block a user