1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-13 14:53:33 +00:00

[AC-2420] Hide SM checkbox on member invite when org is on SM Standalone (#8644)

* Refactoring

* Hide SM toggle on member invite and default to true for SM standalone org

* changed from hide sm checkbox to default and disable

* Removed errant addition from conflict resolution
This commit is contained in:
Alex Morask
2024-04-18 11:21:11 -04:00
committed by GitHub
parent a45706cde7
commit adb1ee3d38
8 changed files with 61 additions and 2 deletions

View File

@@ -1052,6 +1052,7 @@ const safeProviders: SafeProvider[] = [
useClass: OrganizationBillingService,
deps: [
ApiServiceAbstraction,
BillingApiServiceAbstraction,
CryptoServiceAbstraction,
EncryptService,
I18nServiceAbstraction,

View File

@@ -1,5 +1,6 @@
import { SubscriptionCancellationRequest } from "../../billing/models/request/subscription-cancellation.request";
import { OrganizationBillingStatusResponse } from "../../billing/models/response/organization-billing-status.response";
import { OrganizationSubscriptionResponse } from "../../billing/models/response/organization-subscription.response";
import { PlanResponse } from "../../billing/models/response/plan.response";
import { ListResponse } from "../../models/response/list.response";
import { CreateClientOrganizationRequest } from "../models/request/create-client-organization.request";
@@ -11,12 +12,16 @@ export abstract class BillingApiServiceAbstraction {
organizationId: string,
request: SubscriptionCancellationRequest,
) => Promise<void>;
cancelPremiumUserSubscription: (request: SubscriptionCancellationRequest) => Promise<void>;
createClientOrganization: (
providerId: string,
request: CreateClientOrganizationRequest,
) => Promise<void>;
getBillingStatus: (id: string) => Promise<OrganizationBillingStatusResponse>;
getOrganizationSubscription: (
organizationId: string,
) => Promise<OrganizationSubscriptionResponse>;
getPlans: () => Promise<ListResponse<PlanResponse>>;
getProviderSubscription: (providerId: string) => Promise<ProviderSubscriptionResponse>;
updateClientOrganization: (

View File

@@ -41,6 +41,8 @@ export type SubscriptionInformation = {
};
export abstract class OrganizationBillingServiceAbstraction {
isOnSecretsManagerStandalone: (organizationId: string) => Promise<boolean>;
purchaseSubscription: (subscription: SubscriptionInformation) => Promise<OrganizationResponse>;
startFree: (subscription: SubscriptionInformation) => Promise<OrganizationResponse>;

View File

@@ -2,6 +2,7 @@ import { ApiService } from "../../abstractions/api.service";
import { BillingApiServiceAbstraction } from "../../billing/abstractions/billilng-api.service.abstraction";
import { SubscriptionCancellationRequest } from "../../billing/models/request/subscription-cancellation.request";
import { OrganizationBillingStatusResponse } from "../../billing/models/response/organization-billing-status.response";
import { OrganizationSubscriptionResponse } from "../../billing/models/response/organization-subscription.response";
import { PlanResponse } from "../../billing/models/response/plan.response";
import { ListResponse } from "../../models/response/list.response";
import { CreateClientOrganizationRequest } from "../models/request/create-client-organization.request";
@@ -49,10 +50,22 @@ export class BillingApiService implements BillingApiServiceAbstraction {
true,
true,
);
return new OrganizationBillingStatusResponse(r);
}
async getOrganizationSubscription(
organizationId: string,
): Promise<OrganizationSubscriptionResponse> {
const r = await this.apiService.send(
"GET",
"/organizations/" + organizationId + "/subscription",
null,
true,
true,
);
return new OrganizationSubscriptionResponse(r);
}
async getPlans(): Promise<ListResponse<PlanResponse>> {
const r = await this.apiService.send("GET", "/plans", null, false, true);
return new ListResponse(r, PlanResponse);

View File

@@ -9,6 +9,7 @@ import { I18nService } from "../../platform/abstractions/i18n.service";
import { EncString } from "../../platform/models/domain/enc-string";
import { OrgKey } from "../../types/key";
import { SyncService } from "../../vault/abstractions/sync/sync.service.abstraction";
import { BillingApiServiceAbstraction as BillingApiService } from "../abstractions/billilng-api.service.abstraction";
import {
OrganizationBillingServiceAbstraction,
OrganizationInformation,
@@ -28,6 +29,7 @@ interface OrganizationKeys {
export class OrganizationBillingService implements OrganizationBillingServiceAbstraction {
constructor(
private apiService: ApiService,
private billingApiService: BillingApiService,
private cryptoService: CryptoService,
private encryptService: EncryptService,
private i18nService: I18nService,
@@ -35,6 +37,19 @@ export class OrganizationBillingService implements OrganizationBillingServiceAbs
private syncService: SyncService,
) {}
async isOnSecretsManagerStandalone(organizationId: string): Promise<boolean> {
const response = await this.billingApiService.getOrganizationSubscription(organizationId);
if (response.customerDiscount?.id === "sm-standalone") {
const productIds = response.subscription.items.map((item) => item.productId);
return (
response.customerDiscount?.appliesTo.filter((appliesToProductId) =>
productIds.includes(appliesToProductId),
).length > 0
);
}
return false;
}
async purchaseSubscription(subscription: SubscriptionInformation): Promise<OrganizationResponse> {
const request = new OrganizationCreateRequest();