1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-19 10:54:00 +00:00

[PM-32075] Fix self host bug due to type mismatch (#18919)

* fix self host bug with data model

* fix type issues

* fix types, make successful required
This commit is contained in:
Brandon Treston
2026-02-13 10:02:36 -05:00
committed by jaasen-livefront
parent faea15f110
commit 485f620367
9 changed files with 24 additions and 23 deletions

View File

@@ -9,7 +9,6 @@ import {
} from "@bitwarden/common/admin-console/enums";
import { ProviderUserBulkResponse } from "@bitwarden/common/admin-console/models/response/provider/provider-user-bulk.response";
import { ProviderUserUserDetailsResponse } from "@bitwarden/common/admin-console/models/response/provider/provider-user.response";
import { ListResponse } from "@bitwarden/common/models/response/list.response";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { DIALOG_DATA, DialogConfig, DialogService } from "@bitwarden/components";
@@ -34,7 +33,7 @@ type BulkStatusEntry = {
type BulkStatusDialogData = {
users: Array<OrganizationUserView | ProviderUserUserDetailsResponse>;
filteredUsers: Array<OrganizationUserView | ProviderUserUserDetailsResponse>;
request: Promise<ListResponse<OrganizationUserBulkResponse | ProviderUserBulkResponse>>;
request: Promise<OrganizationUserBulkResponse[] | ProviderUserBulkResponse[]>;
successfulMessage: string;
};
@@ -63,7 +62,7 @@ export class BulkStatusComponent implements OnInit {
async showBulkStatus(data: BulkStatusDialogData) {
try {
const response = await data.request;
const keyedErrors: any = response.data
const keyedErrors: any = (response ?? [])
.filter((r) => r.error !== "")
.reduce((a, x) => ({ ...a, [x.id]: x.error }), {});
const keyedFilteredUsers: any = data.filteredUsers.reduce(

View File

@@ -446,7 +446,7 @@ export class MembersComponent extends BaseMembersComponent<OrganizationUserView>
try {
const result = await this.memberActionsService.bulkReinvite(organization, filteredUsers);
if (!result.successful) {
if (result.successful.length === 0) {
throw new Error();
}

View File

@@ -515,7 +515,7 @@ describe("vNextMembersComponent", () => {
};
jest.spyOn(component["dataSource"](), "isIncreasedBulkLimitEnabled").mockReturnValue(false);
jest.spyOn(component["dataSource"](), "getCheckedUsers").mockReturnValue([invitedUser]);
mockMemberActionsService.bulkReinvite.mockResolvedValue({ successful: true });
mockMemberActionsService.bulkReinvite.mockResolvedValue({ successful: [{}], failed: [] });
await component.bulkReinvite(mockOrg);
@@ -549,7 +549,7 @@ describe("vNextMembersComponent", () => {
jest.spyOn(component["dataSource"](), "isIncreasedBulkLimitEnabled").mockReturnValue(false);
jest.spyOn(component["dataSource"](), "getCheckedUsers").mockReturnValue([invitedUser]);
const error = new Error("Bulk reinvite failed");
mockMemberActionsService.bulkReinvite.mockResolvedValue({ successful: false, failed: error });
mockMemberActionsService.bulkReinvite.mockResolvedValue({ successful: [], failed: error });
await component.bulkReinvite(mockOrg);

View File

@@ -426,7 +426,7 @@ export class vNextMembersComponent {
const result = await this.memberActionsService.bulkReinvite(organization, filteredUsers);
if (!result.successful) {
if (result.successful.length === 0) {
this.validationService.showError(result.failed);
}

View File

@@ -507,7 +507,7 @@ describe("MemberActionsService", () => {
const result = await service.bulkReinvite(mockOrganization, users);
expect(result.successful).toBeUndefined();
expect(result.successful).toHaveLength(0);
expect(result.failed).toHaveLength(totalUsers);
expect(result.failed.every((f) => f.error === errorMessage)).toBe(true);
expect(organizationUserApiService.postManyOrganizationUserReinvite).toHaveBeenCalledTimes(2);

View File

@@ -37,11 +37,7 @@ export interface MemberActionResult {
}
export class BulkActionResult {
constructor() {
this.failed = [];
}
successful?: OrganizationUserBulkResponse[];
successful: OrganizationUserBulkResponse[] = [];
failed: { id: string; error: string }[] = [];
}
@@ -316,7 +312,7 @@ export class MemberActionsService {
}
return {
successful: allSuccessful.length > 0 ? allSuccessful : undefined,
successful: allSuccessful,
failed: allFailed,
};
}

View File

@@ -1,8 +1,10 @@
import { Injectable, WritableSignal } from "@angular/core";
import { firstValueFrom, lastValueFrom } from "rxjs";
import { OrganizationUserBulkResponse } from "@bitwarden/admin-console/common";
import { UserNamePipe } from "@bitwarden/angular/pipes/user-name.pipe";
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
import { ProviderUserBulkResponse } from "@bitwarden/common/admin-console/models/response/provider/provider-user-bulk.response";
import { ProductTierType } from "@bitwarden/common/billing/enums";
import { OrganizationBillingMetadataResponse } from "@bitwarden/common/billing/models/response/organization-billing-metadata.response";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
@@ -197,7 +199,7 @@ export class MemberDialogManagerService {
async openBulkStatusDialog(
users: OrganizationUserView[],
filteredUsers: OrganizationUserView[],
request: Promise<any>,
request: Promise<OrganizationUserBulkResponse[] | ProviderUserBulkResponse[]>,
successMessage: string,
): Promise<void> {
const dialogRef = BulkStatusComponent.open(this.dialogService, {

View File

@@ -223,10 +223,12 @@ export class MembersComponent extends BaseMembersComponent<ProviderUser> {
}
} else {
// Feature flag disabled - show legacy dialog
const request = this.apiService.postManyProviderUserReinvite(
this.providerId,
new ProviderUserBulkRequest(checkedInvitedUsers.map((user) => user.id)),
);
const request = this.apiService
.postManyProviderUserReinvite(
this.providerId,
new ProviderUserBulkRequest(checkedInvitedUsers.map((user) => user.id)),
)
.then((response) => response.data);
const dialogRef = BulkStatusComponent.open(this.dialogService, {
data: {

View File

@@ -236,10 +236,12 @@ export class vNextMembersComponent {
}
} else {
// In self-hosted environments, show legacy dialog
const request = this.apiService.postManyProviderUserReinvite(
providerId,
new ProviderUserBulkRequest(checkedInvitedUsers.map((user) => user.id)),
);
const request = this.apiService
.postManyProviderUserReinvite(
providerId,
new ProviderUserBulkRequest(checkedInvitedUsers.map((user) => user.id)),
)
.then((response) => response.data);
const dialogRef = BulkStatusComponent.open(this.dialogService, {
data: {