mirror of
https://github.com/bitwarden/browser
synced 2025-12-15 15:53:27 +00:00
[PM-12425] Remove FF: AC-2828_provider-portal-members-page (#11241)
* Remove FF: AC-2828_provider-portal-members-page * Thomas' feedback: Fix provider layout
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
import { DIALOG_DATA, DialogConfig } from "@angular/cdk/dialog";
|
||||
import { Component, Inject } from "@angular/core";
|
||||
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
||||
import { firstValueFrom, map, Observable, switchMap } from "rxjs";
|
||||
|
||||
import {
|
||||
OrganizationUserApiService,
|
||||
OrganizationUserBulkConfirmRequest,
|
||||
OrganizationUserBulkPublicKeyResponse,
|
||||
OrganizationUserBulkResponse,
|
||||
} from "@bitwarden/admin-console/common";
|
||||
import { OrganizationUserStatusType } from "@bitwarden/common/admin-console/enums";
|
||||
import { ProviderUserBulkPublicKeyResponse } from "@bitwarden/common/admin-console/models/response/provider/provider-user-bulk-public-key.response";
|
||||
import { ProviderUserBulkResponse } from "@bitwarden/common/admin-console/models/response/provider/provider-user-bulk.response";
|
||||
import { ListResponse } from "@bitwarden/common/models/response/list.response";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
|
||||
import { StateProvider } from "@bitwarden/common/platform/state";
|
||||
import { OrganizationId } from "@bitwarden/common/types/guid";
|
||||
import { OrgKey } from "@bitwarden/common/types/key";
|
||||
import { DialogService } from "@bitwarden/components";
|
||||
|
||||
import { BaseBulkConfirmComponent } from "./base-bulk-confirm.component";
|
||||
import { BulkUserDetails } from "./bulk-status.component";
|
||||
|
||||
type BulkConfirmDialogParams = {
|
||||
organizationId: string;
|
||||
users: BulkUserDetails[];
|
||||
};
|
||||
|
||||
@Component({
|
||||
templateUrl: "bulk-confirm-dialog.component.html",
|
||||
})
|
||||
export class BulkConfirmDialogComponent extends BaseBulkConfirmComponent {
|
||||
organizationId: string;
|
||||
organizationKey$: Observable<OrgKey>;
|
||||
users: BulkUserDetails[];
|
||||
|
||||
constructor(
|
||||
protected cryptoService: CryptoService,
|
||||
@Inject(DIALOG_DATA) protected dialogParams: BulkConfirmDialogParams,
|
||||
protected encryptService: EncryptService,
|
||||
private organizationUserApiService: OrganizationUserApiService,
|
||||
protected i18nService: I18nService,
|
||||
private stateProvider: StateProvider,
|
||||
) {
|
||||
super(cryptoService, encryptService, i18nService);
|
||||
|
||||
this.organizationId = dialogParams.organizationId;
|
||||
this.organizationKey$ = this.stateProvider.activeUserId$.pipe(
|
||||
switchMap((userId) => this.cryptoService.orgKeys$(userId)),
|
||||
map((organizationKeysById) => organizationKeysById[this.organizationId as OrganizationId]),
|
||||
takeUntilDestroyed(),
|
||||
);
|
||||
this.users = dialogParams.users;
|
||||
}
|
||||
|
||||
protected getCryptoKey = async (): Promise<SymmetricCryptoKey> =>
|
||||
await firstValueFrom(this.organizationKey$);
|
||||
|
||||
protected getPublicKeys = async (): Promise<
|
||||
ListResponse<OrganizationUserBulkPublicKeyResponse | ProviderUserBulkPublicKeyResponse>
|
||||
> =>
|
||||
await this.organizationUserApiService.postOrganizationUsersPublicKey(
|
||||
this.organizationId,
|
||||
this.filteredUsers.map((user) => user.id),
|
||||
);
|
||||
|
||||
protected isAccepted = (user: BulkUserDetails) =>
|
||||
user.status === OrganizationUserStatusType.Accepted;
|
||||
|
||||
protected postConfirmRequest = async (
|
||||
userIdsWithKeys: { id: string; key: string }[],
|
||||
): Promise<ListResponse<OrganizationUserBulkResponse | ProviderUserBulkResponse>> => {
|
||||
const request = new OrganizationUserBulkConfirmRequest(userIdsWithKeys);
|
||||
return await this.organizationUserApiService.postOrganizationUserBulkConfirm(
|
||||
this.organizationId,
|
||||
request,
|
||||
);
|
||||
};
|
||||
|
||||
static open(dialogService: DialogService, config: DialogConfig<BulkConfirmDialogParams>) {
|
||||
return dialogService.open(BulkConfirmDialogComponent, config);
|
||||
}
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
import { DIALOG_DATA, DialogConfig } from "@angular/cdk/dialog";
|
||||
import { Component, Inject, OnInit } from "@angular/core";
|
||||
|
||||
import {
|
||||
OrganizationUserApiService,
|
||||
OrganizationUserBulkConfirmRequest,
|
||||
} from "@bitwarden/admin-console/common";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { OrganizationUserStatusType } from "@bitwarden/common/admin-console/enums";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
|
||||
import { DialogService } from "@bitwarden/components";
|
||||
|
||||
import { BulkUserDetails } from "./bulk-status.component";
|
||||
|
||||
type BulkConfirmDialogData = {
|
||||
organizationId: string;
|
||||
users: BulkUserDetails[];
|
||||
};
|
||||
|
||||
@Component({
|
||||
selector: "app-bulk-confirm",
|
||||
templateUrl: "bulk-confirm.component.html",
|
||||
})
|
||||
export class BulkConfirmComponent implements OnInit {
|
||||
organizationId: string;
|
||||
users: BulkUserDetails[];
|
||||
|
||||
excludedUsers: BulkUserDetails[];
|
||||
filteredUsers: BulkUserDetails[];
|
||||
publicKeys: Map<string, Uint8Array> = new Map();
|
||||
fingerprints: Map<string, string> = new Map();
|
||||
statuses: Map<string, string> = new Map();
|
||||
|
||||
loading = true;
|
||||
done = false;
|
||||
error: string;
|
||||
|
||||
constructor(
|
||||
@Inject(DIALOG_DATA) protected data: BulkConfirmDialogData,
|
||||
protected cryptoService: CryptoService,
|
||||
protected encryptService: EncryptService,
|
||||
protected apiService: ApiService,
|
||||
private organizationUserApiService: OrganizationUserApiService,
|
||||
private i18nService: I18nService,
|
||||
) {
|
||||
this.organizationId = data.organizationId;
|
||||
this.users = data.users;
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
this.excludedUsers = this.users.filter((u) => !this.isAccepted(u));
|
||||
this.filteredUsers = this.users.filter((u) => this.isAccepted(u));
|
||||
|
||||
if (this.filteredUsers.length <= 0) {
|
||||
this.done = true;
|
||||
}
|
||||
|
||||
const response = await this.getPublicKeys();
|
||||
|
||||
for (const entry of response.data) {
|
||||
const publicKey = Utils.fromB64ToArray(entry.key);
|
||||
const fingerprint = await this.cryptoService.getFingerprint(entry.userId, publicKey);
|
||||
if (fingerprint != null) {
|
||||
this.publicKeys.set(entry.id, publicKey);
|
||||
this.fingerprints.set(entry.id, fingerprint.join("-"));
|
||||
}
|
||||
}
|
||||
|
||||
this.loading = false;
|
||||
}
|
||||
|
||||
async submit() {
|
||||
this.loading = true;
|
||||
try {
|
||||
const key = await this.getCryptoKey();
|
||||
const userIdsWithKeys: any[] = [];
|
||||
for (const user of this.filteredUsers) {
|
||||
const publicKey = this.publicKeys.get(user.id);
|
||||
if (publicKey == null) {
|
||||
continue;
|
||||
}
|
||||
const encryptedKey = await this.encryptService.rsaEncrypt(key.key, publicKey);
|
||||
userIdsWithKeys.push({
|
||||
id: user.id,
|
||||
key: encryptedKey.encryptedString,
|
||||
});
|
||||
}
|
||||
const response = await this.postConfirmRequest(userIdsWithKeys);
|
||||
|
||||
response.data.forEach((entry) => {
|
||||
const error = entry.error !== "" ? entry.error : this.i18nService.t("bulkConfirmMessage");
|
||||
this.statuses.set(entry.id, error);
|
||||
});
|
||||
|
||||
this.done = true;
|
||||
} catch (e) {
|
||||
this.error = e.message;
|
||||
}
|
||||
this.loading = false;
|
||||
}
|
||||
|
||||
protected isAccepted(user: BulkUserDetails) {
|
||||
return user.status === OrganizationUserStatusType.Accepted;
|
||||
}
|
||||
|
||||
protected async getPublicKeys() {
|
||||
return await this.organizationUserApiService.postOrganizationUsersPublicKey(
|
||||
this.organizationId,
|
||||
this.filteredUsers.map((user) => user.id),
|
||||
);
|
||||
}
|
||||
|
||||
protected getCryptoKey(): Promise<SymmetricCryptoKey> {
|
||||
return this.cryptoService.getOrgKey(this.organizationId);
|
||||
}
|
||||
|
||||
protected async postConfirmRequest(userIdsWithKeys: any[]) {
|
||||
const request = new OrganizationUserBulkConfirmRequest(userIdsWithKeys);
|
||||
return await this.organizationUserApiService.postOrganizationUserBulkConfirm(
|
||||
this.organizationId,
|
||||
request,
|
||||
);
|
||||
}
|
||||
|
||||
static open(dialogService: DialogService, config: DialogConfig<BulkConfirmDialogData>) {
|
||||
return dialogService.open(BulkConfirmComponent, config);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
import { DIALOG_DATA, DialogConfig } from "@angular/cdk/dialog";
|
||||
import { Component, Inject } from "@angular/core";
|
||||
|
||||
import {
|
||||
OrganizationUserApiService,
|
||||
OrganizationUserBulkResponse,
|
||||
} from "@bitwarden/admin-console/common";
|
||||
import { OrganizationUserStatusType } from "@bitwarden/common/admin-console/enums";
|
||||
import { ListResponse } from "@bitwarden/common/models/response/list.response";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { DialogService } from "@bitwarden/components";
|
||||
|
||||
import { BaseBulkRemoveComponent } from "./base-bulk-remove.component";
|
||||
import { BulkUserDetails } from "./bulk-status.component";
|
||||
|
||||
type BulkRemoveDialogParams = {
|
||||
organizationId: string;
|
||||
users: BulkUserDetails[];
|
||||
};
|
||||
|
||||
@Component({
|
||||
templateUrl: "bulk-remove-dialog.component.html",
|
||||
})
|
||||
export class BulkRemoveDialogComponent extends BaseBulkRemoveComponent {
|
||||
organizationId: string;
|
||||
users: BulkUserDetails[];
|
||||
|
||||
constructor(
|
||||
@Inject(DIALOG_DATA) protected dialogParams: BulkRemoveDialogParams,
|
||||
protected i18nService: I18nService,
|
||||
private organizationUserApiService: OrganizationUserApiService,
|
||||
) {
|
||||
super(i18nService);
|
||||
this.organizationId = dialogParams.organizationId;
|
||||
this.users = dialogParams.users;
|
||||
this.showNoMasterPasswordWarning = this.users.some(
|
||||
(u) => u.status > OrganizationUserStatusType.Invited && u.hasMasterPassword === false,
|
||||
);
|
||||
}
|
||||
|
||||
protected deleteUsers = (): Promise<ListResponse<OrganizationUserBulkResponse>> =>
|
||||
this.organizationUserApiService.removeManyOrganizationUsers(
|
||||
this.organizationId,
|
||||
this.users.map((user) => user.id),
|
||||
);
|
||||
|
||||
protected get removeUsersWarning() {
|
||||
return this.i18nService.t("removeOrgUsersConfirmation");
|
||||
}
|
||||
|
||||
static open(dialogService: DialogService, config: DialogConfig<BulkRemoveDialogParams>) {
|
||||
return dialogService.open(BulkRemoveDialogComponent, config);
|
||||
}
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
import { DIALOG_DATA, DialogConfig } from "@angular/cdk/dialog";
|
||||
import { Component, Inject } from "@angular/core";
|
||||
|
||||
import { OrganizationUserApiService } from "@bitwarden/admin-console/common";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { OrganizationUserStatusType } from "@bitwarden/common/admin-console/enums";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { DialogService } from "@bitwarden/components";
|
||||
|
||||
import { BulkUserDetails } from "./bulk-status.component";
|
||||
|
||||
type BulkRemoveDialogData = {
|
||||
organizationId: string;
|
||||
users: BulkUserDetails[];
|
||||
};
|
||||
|
||||
@Component({
|
||||
selector: "app-bulk-remove",
|
||||
templateUrl: "bulk-remove.component.html",
|
||||
})
|
||||
export class BulkRemoveComponent {
|
||||
organizationId: string;
|
||||
users: BulkUserDetails[];
|
||||
|
||||
statuses: Map<string, string> = new Map();
|
||||
|
||||
loading = false;
|
||||
done = false;
|
||||
error: string;
|
||||
showNoMasterPasswordWarning = false;
|
||||
|
||||
constructor(
|
||||
@Inject(DIALOG_DATA) protected data: BulkRemoveDialogData,
|
||||
protected apiService: ApiService,
|
||||
protected i18nService: I18nService,
|
||||
private organizationUserApiService: OrganizationUserApiService,
|
||||
) {
|
||||
this.organizationId = data.organizationId;
|
||||
this.users = data.users;
|
||||
this.showNoMasterPasswordWarning = this.users.some(
|
||||
(u) => u.status > OrganizationUserStatusType.Invited && u.hasMasterPassword === false,
|
||||
);
|
||||
}
|
||||
|
||||
submit = async () => {
|
||||
this.loading = true;
|
||||
try {
|
||||
const response = await this.removeUsers();
|
||||
|
||||
response.data.forEach((entry) => {
|
||||
const error = entry.error !== "" ? entry.error : this.i18nService.t("bulkRemovedMessage");
|
||||
this.statuses.set(entry.id, error);
|
||||
});
|
||||
this.done = true;
|
||||
} catch (e) {
|
||||
this.error = e.message;
|
||||
}
|
||||
|
||||
this.loading = false;
|
||||
};
|
||||
|
||||
protected async removeUsers() {
|
||||
return await this.organizationUserApiService.removeManyOrganizationUsers(
|
||||
this.organizationId,
|
||||
this.users.map((user) => user.id),
|
||||
);
|
||||
}
|
||||
|
||||
protected get removeUsersWarning() {
|
||||
return this.i18nService.t("removeOrgUsersConfirmation");
|
||||
}
|
||||
|
||||
static open(dialogService: DialogService, config: DialogConfig<BulkRemoveDialogData>) {
|
||||
return dialogService.open(BulkRemoveComponent, config);
|
||||
}
|
||||
}
|
||||
@@ -60,9 +60,9 @@ import { GroupService } from "../core";
|
||||
import { OrganizationUserView } from "../core/views/organization-user.view";
|
||||
import { openEntityEventsDialog } from "../manage/entity-events.component";
|
||||
|
||||
import { BulkConfirmComponent } from "./components/bulk/bulk-confirm.component";
|
||||
import { BulkConfirmDialogComponent } from "./components/bulk/bulk-confirm-dialog.component";
|
||||
import { BulkEnableSecretsManagerDialogComponent } from "./components/bulk/bulk-enable-sm-dialog.component";
|
||||
import { BulkRemoveComponent } from "./components/bulk/bulk-remove.component";
|
||||
import { BulkRemoveDialogComponent } from "./components/bulk/bulk-remove-dialog.component";
|
||||
import { BulkRestoreRevokeComponent } from "./components/bulk/bulk-restore-revoke.component";
|
||||
import { BulkStatusComponent } from "./components/bulk/bulk-status.component";
|
||||
import {
|
||||
@@ -541,7 +541,7 @@ export class MembersComponent extends BaseMembersComponent<OrganizationUserView>
|
||||
return;
|
||||
}
|
||||
|
||||
const dialogRef = BulkRemoveComponent.open(this.dialogService, {
|
||||
const dialogRef = BulkRemoveDialogComponent.open(this.dialogService, {
|
||||
data: {
|
||||
organizationId: this.organization.id,
|
||||
users: this.dataSource.getCheckedUsers(),
|
||||
@@ -620,7 +620,7 @@ export class MembersComponent extends BaseMembersComponent<OrganizationUserView>
|
||||
return;
|
||||
}
|
||||
|
||||
const dialogRef = BulkConfirmComponent.open(this.dialogService, {
|
||||
const dialogRef = BulkConfirmDialogComponent.open(this.dialogService, {
|
||||
data: {
|
||||
organizationId: this.organization.id,
|
||||
users: this.dataSource.getCheckedUsers(),
|
||||
|
||||
@@ -7,9 +7,9 @@ import { PasswordCalloutComponent } from "@bitwarden/auth/angular";
|
||||
import { LooseComponentsModule } from "../../../shared";
|
||||
import { SharedOrganizationModule } from "../shared";
|
||||
|
||||
import { BulkConfirmComponent } from "./components/bulk/bulk-confirm.component";
|
||||
import { BulkConfirmDialogComponent } from "./components/bulk/bulk-confirm-dialog.component";
|
||||
import { BulkEnableSecretsManagerDialogComponent } from "./components/bulk/bulk-enable-sm-dialog.component";
|
||||
import { BulkRemoveComponent } from "./components/bulk/bulk-remove.component";
|
||||
import { BulkRemoveDialogComponent } from "./components/bulk/bulk-remove-dialog.component";
|
||||
import { BulkRestoreRevokeComponent } from "./components/bulk/bulk-restore-revoke.component";
|
||||
import { BulkStatusComponent } from "./components/bulk/bulk-status.component";
|
||||
import { UserDialogModule } from "./components/member-dialog";
|
||||
@@ -28,9 +28,9 @@ import { MembersComponent } from "./members.component";
|
||||
PasswordStrengthV2Component,
|
||||
],
|
||||
declarations: [
|
||||
BulkConfirmComponent,
|
||||
BulkConfirmDialogComponent,
|
||||
BulkEnableSecretsManagerDialogComponent,
|
||||
BulkRemoveComponent,
|
||||
BulkRemoveDialogComponent,
|
||||
BulkRestoreRevokeComponent,
|
||||
BulkStatusComponent,
|
||||
MembersComponent,
|
||||
|
||||
Reference in New Issue
Block a user