1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-16 08:13:42 +00:00

[PM-18870] Convert Organization to Business Unit (#14131)

* Add setupBusinessUnit to OrganizationBillingApiService

* Add setup-business-unit.component

* Updated designs and cleanup work

* Update existing logos for Provider Portal and Admin Console

* Fix broken test
This commit is contained in:
Alex Morask
2025-04-10 10:06:23 -04:00
committed by GitHub
parent 5a1b0744f0
commit eea0bb6d6e
23 changed files with 380 additions and 27 deletions

View File

@@ -1,5 +1,5 @@
export enum ProviderType {
Msp = 0,
Reseller = 1,
MultiOrganizationEnterprise = 2,
BusinessUnit = 2,
}

View File

@@ -1,4 +1,9 @@
import { ProviderStatusType, ProviderUserStatusType, ProviderUserType } from "../../enums";
import {
ProviderStatusType,
ProviderType,
ProviderUserStatusType,
ProviderUserType,
} from "../../enums";
import { ProfileProviderResponse } from "../response/profile-provider.response";
export class ProviderData {
@@ -10,6 +15,7 @@ export class ProviderData {
userId: string;
useEvents: boolean;
providerStatus: ProviderStatusType;
providerType: ProviderType;
constructor(response: ProfileProviderResponse) {
this.id = response.id;
@@ -20,5 +26,6 @@ export class ProviderData {
this.userId = response.userId;
this.useEvents = response.useEvents;
this.providerStatus = response.providerStatus;
this.providerType = response.providerType;
}
}

View File

@@ -331,8 +331,7 @@ export class Organization {
get hasBillableProvider() {
return (
this.hasProvider &&
(this.providerType === ProviderType.Msp ||
this.providerType === ProviderType.MultiOrganizationEnterprise)
(this.providerType === ProviderType.Msp || this.providerType === ProviderType.BusinessUnit)
);
}

View File

@@ -1,6 +1,11 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { ProviderStatusType, ProviderUserStatusType, ProviderUserType } from "../../enums";
import {
ProviderStatusType,
ProviderType,
ProviderUserStatusType,
ProviderUserType,
} from "../../enums";
import { ProviderData } from "../data/provider.data";
export class Provider {
@@ -12,6 +17,7 @@ export class Provider {
userId: string;
useEvents: boolean;
providerStatus: ProviderStatusType;
providerType: ProviderType;
constructor(obj?: ProviderData) {
if (obj == null) {
@@ -26,6 +32,7 @@ export class Provider {
this.userId = obj.userId;
this.useEvents = obj.useEvents;
this.providerStatus = obj.providerStatus;
this.providerType = obj.providerType;
}
get canAccess() {

View File

@@ -1,5 +1,10 @@
import { BaseResponse } from "../../../models/response/base.response";
import { ProviderStatusType, ProviderUserStatusType, ProviderUserType } from "../../enums";
import {
ProviderStatusType,
ProviderType,
ProviderUserStatusType,
ProviderUserType,
} from "../../enums";
import { PermissionsApi } from "../api/permissions.api";
export class ProfileProviderResponse extends BaseResponse {
@@ -13,6 +18,7 @@ export class ProfileProviderResponse extends BaseResponse {
userId: string;
useEvents: boolean;
providerStatus: ProviderStatusType;
providerType: ProviderType;
constructor(response: any) {
super(response);
@@ -26,5 +32,6 @@ export class ProfileProviderResponse extends BaseResponse {
this.userId = this.getResponseProperty("UserId");
this.useEvents = this.getResponseProperty("UseEvents");
this.providerStatus = this.getResponseProperty("ProviderStatus");
this.providerType = this.getResponseProperty("ProviderType");
}
}

View File

@@ -4,7 +4,12 @@ import { FakeAccountService, FakeStateProvider, mockAccountServiceWith } from ".
import { FakeActiveUserState, FakeSingleUserState } from "../../../spec/fake-state";
import { Utils } from "../../platform/misc/utils";
import { UserId } from "../../types/guid";
import { ProviderStatusType, ProviderUserStatusType, ProviderUserType } from "../enums";
import {
ProviderStatusType,
ProviderType,
ProviderUserStatusType,
ProviderUserType,
} from "../enums";
import { ProviderData } from "../models/data/provider.data";
import { Provider } from "../models/domain/provider";
@@ -67,6 +72,7 @@ describe("PROVIDERS key definition", () => {
userId: "string",
useEvents: true,
providerStatus: ProviderStatusType.Pending,
providerType: ProviderType.Msp,
},
};
const result = sut.deserializer(JSON.parse(JSON.stringify(expectedResult)));

View File

@@ -1,19 +1,27 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import {
BillingInvoiceResponse,
BillingTransactionResponse,
} from "../../models/response/billing.response";
export class OrganizationBillingApiServiceAbstraction {
getBillingInvoices: (
export abstract class OrganizationBillingApiServiceAbstraction {
abstract getBillingInvoices: (
id: string,
status?: string,
startAfter?: string,
) => Promise<BillingInvoiceResponse[]>;
getBillingTransactions: (
abstract getBillingTransactions: (
id: string,
startAfter?: string,
) => Promise<BillingTransactionResponse[]>;
abstract setupBusinessUnit: (
id: string,
request: {
userId: string;
token: string;
providerKey: string;
organizationKey: string;
},
) => Promise<string>;
}

View File

@@ -49,4 +49,24 @@ export class OrganizationBillingApiService implements OrganizationBillingApiServ
);
return r?.map((i: any) => new BillingTransactionResponse(i)) || [];
}
async setupBusinessUnit(
id: string,
request: {
userId: string;
token: string;
providerKey: string;
organizationKey: string;
},
): Promise<string> {
const response = await this.apiService.send(
"POST",
`/organizations/${id}/billing/setup-business-unit`,
request,
true,
true,
);
return response as string;
}
}