+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
- {{ "startYour7DayFreeTrialOfBitwardenFor" | i18n: orgDisplayName }}
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+ {{ freeTrialText }}
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
diff --git a/apps/web/src/app/auth/trial-initiation/trial-initiation.component.ts b/apps/web/src/app/auth/trial-initiation/trial-initiation.component.ts
index 002e1687e0..279c23d553 100644
--- a/apps/web/src/app/auth/trial-initiation/trial-initiation.component.ts
+++ b/apps/web/src/app/auth/trial-initiation/trial-initiation.component.ts
@@ -18,6 +18,7 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service"
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
import { RouterService } from "./../../core/router.service";
+import { SubscriptionType } from "./secrets-manager/secrets-manager-trial-billing-step.component";
import { VerticalStepperComponent } from "./vertical-stepper/vertical-stepper.component";
enum ValidOrgParams {
@@ -44,6 +45,7 @@ enum ValidLayoutParams {
cnetcmpgnteams = "cnetcmpgnteams",
abmenterprise = "abmenterprise",
abmteams = "abmteams",
+ secretsManager = "secretsManager",
}
@Component({
@@ -77,6 +79,7 @@ export class TrialInitiationComponent implements OnInit, OnDestroy {
ValidOrgParams.individual,
];
layouts = ValidLayoutParams;
+ orgTypes = ValidOrgParams;
referenceData: ReferenceEventRequest;
@ViewChild("stepper", { static: false }) verticalStepper: VerticalStepperComponent;
@@ -258,6 +261,15 @@ export class TrialInitiationComponent implements OnInit, OnDestroy {
return this.org;
}
+ get freeTrialText() {
+ const translationKey =
+ this.layout === this.layouts.secretsManager
+ ? "startYour7DayFreeTrialOfBitwardenSecretsManagerFor"
+ : "startYour7DayFreeTrialOfBitwardenFor";
+
+ return this.i18nService.t(translationKey, this.org);
+ }
+
private setupFamilySponsorship(sponsorshipToken: string) {
if (sponsorshipToken != null) {
const route = this.router.createUrlTree(["setup/families-for-enterprise"], {
@@ -266,4 +278,6 @@ export class TrialInitiationComponent implements OnInit, OnDestroy {
this.routerService.setPreviousUrl(route.toString());
}
}
+
+ protected readonly SubscriptionType = SubscriptionType;
}
diff --git a/apps/web/src/app/auth/trial-initiation/trial-initiation.module.ts b/apps/web/src/app/auth/trial-initiation/trial-initiation.module.ts
index 0e014bfcfc..52f11def9e 100644
--- a/apps/web/src/app/auth/trial-initiation/trial-initiation.module.ts
+++ b/apps/web/src/app/auth/trial-initiation/trial-initiation.module.ts
@@ -6,6 +6,9 @@ import { FormFieldModule } from "@bitwarden/components";
import { OrganizationCreateModule } from "../../admin-console/organizations/create/organization-create.module";
import { RegisterFormModule } from "../../auth/register-form/register-form.module";
+import { SecretsManagerTrialFreeStepperComponent } from "../../auth/trial-initiation/secrets-manager/secrets-manager-trial-free-stepper.component";
+import { SecretsManagerTrialPaidStepperComponent } from "../../auth/trial-initiation/secrets-manager/secrets-manager-trial-paid-stepper.component";
+import { SecretsManagerTrialComponent } from "../../auth/trial-initiation/secrets-manager/secrets-manager-trial.component";
import { PaymentComponent, TaxInfoComponent } from "../../billing";
import { BillingComponent } from "../../billing/accounts/trial-initiation/billing.component";
import { EnvironmentSelectorModule } from "../../components/environment-selector/environment-selector.module";
@@ -25,11 +28,14 @@ import { LogoCnet5StarsComponent } from "./content/logo-cnet-5-stars.component";
import { LogoCnetComponent } from "./content/logo-cnet.component";
import { LogoForbesComponent } from "./content/logo-forbes.component";
import { LogoUSNewsComponent } from "./content/logo-us-news.component";
+import { ReviewBlurbComponent } from "./content/review-blurb.component";
import { ReviewLogoComponent } from "./content/review-logo.component";
+import { SecretsManagerContentComponent } from "./content/secrets-manager-content.component";
import { TeamsContentComponent } from "./content/teams-content.component";
import { Teams1ContentComponent } from "./content/teams1-content.component";
import { Teams2ContentComponent } from "./content/teams2-content.component";
import { Teams3ContentComponent } from "./content/teams3-content.component";
+import { SecretsManagerTrialBillingStepComponent } from "./secrets-manager/secrets-manager-trial-billing-step.component";
import { TrialInitiationComponent } from "./trial-initiation.component";
import { VerticalStepperModule } from "./vertical-stepper/vertical-stepper.module";
@@ -44,6 +50,7 @@ import { VerticalStepperModule } from "./vertical-stepper/vertical-stepper.modul
EnvironmentSelectorModule,
PaymentComponent,
TaxInfoComponent,
+ SecretsManagerTrialBillingStepComponent,
],
declarations: [
TrialInitiationComponent,
@@ -69,6 +76,11 @@ import { VerticalStepperModule } from "./vertical-stepper/vertical-stepper.modul
LogoForbesComponent,
LogoUSNewsComponent,
ReviewLogoComponent,
+ SecretsManagerContentComponent,
+ ReviewBlurbComponent,
+ SecretsManagerTrialComponent,
+ SecretsManagerTrialFreeStepperComponent,
+ SecretsManagerTrialPaidStepperComponent,
],
exports: [TrialInitiationComponent],
providers: [TitleCasePipe],
diff --git a/apps/web/src/app/auth/trial-initiation/vertical-stepper/vertical-step.component.html b/apps/web/src/app/auth/trial-initiation/vertical-stepper/vertical-step.component.html
index 34e3af03a3..427a409917 100644
--- a/apps/web/src/app/auth/trial-initiation/vertical-stepper/vertical-step.component.html
+++ b/apps/web/src/app/auth/trial-initiation/vertical-stepper/vertical-step.component.html
@@ -1,7 +1,10 @@
diff --git a/apps/web/src/app/auth/trial-initiation/vertical-stepper/vertical-step.component.ts b/apps/web/src/app/auth/trial-initiation/vertical-stepper/vertical-step.component.ts
index 1737153224..1ff900875d 100644
--- a/apps/web/src/app/auth/trial-initiation/vertical-stepper/vertical-step.component.ts
+++ b/apps/web/src/app/auth/trial-initiation/vertical-stepper/vertical-step.component.ts
@@ -9,4 +9,5 @@ import { Component, Input } from "@angular/core";
export class VerticalStep extends CdkStep {
@Input() subLabel = "";
@Input() applyBorder = true;
+ @Input() addSubLabelSpacing = false;
}
diff --git a/apps/web/src/app/billing/organizations/organization-subscription-cloud.component.ts b/apps/web/src/app/billing/organizations/organization-subscription-cloud.component.ts
index 1c18ab6fc4..ad9c20bef8 100644
--- a/apps/web/src/app/billing/organizations/organization-subscription-cloud.component.ts
+++ b/apps/web/src/app/billing/organizations/organization-subscription-cloud.component.ts
@@ -140,7 +140,7 @@ export class OrganizationSubscriptionCloudComponent implements OnInit, OnDestroy
get subscriptionLineItems() {
return this.lineItems.map((lineItem: BillingSubscriptionItemResponse) => ({
name: lineItem.name,
- amount: this.discountPrice(lineItem.amount),
+ amount: this.discountPrice(lineItem.amount, lineItem.productId),
quantity: lineItem.quantity,
interval: lineItem.interval,
sponsoredSubscriptionItem: lineItem.sponsoredSubscriptionItem,
@@ -183,7 +183,7 @@ export class OrganizationSubscriptionCloudComponent implements OnInit, OnDestroy
}
get storageGbPrice() {
- return this.discountPrice(this.sub.plan.PasswordManager.additionalStoragePricePerGb);
+ return this.sub.plan.PasswordManager.additionalStoragePricePerGb;
}
get seatPrice() {
@@ -198,14 +198,12 @@ export class OrganizationSubscriptionCloudComponent implements OnInit, OnDestroy
return {
seatCount: this.sub.smSeats,
maxAutoscaleSeats: this.sub.maxAutoscaleSmSeats,
- seatPrice: this.discountPrice(this.sub.plan.SecretsManager.seatPrice),
+ seatPrice: this.sub.plan.SecretsManager.seatPrice,
maxAutoscaleServiceAccounts: this.sub.maxAutoscaleSmServiceAccounts,
additionalServiceAccounts:
this.sub.smServiceAccounts - this.sub.plan.SecretsManager.baseServiceAccount,
interval: this.sub.plan.isAnnual ? "year" : "month",
- additionalServiceAccountPrice: this.discountPrice(
- this.sub.plan.SecretsManager.additionalPricePerServiceAccount,
- ),
+ additionalServiceAccountPrice: this.sub.plan.SecretsManager.additionalPricePerServiceAccount,
baseServiceAccountCount: this.sub.plan.SecretsManager.baseServiceAccount,
};
}
@@ -404,9 +402,12 @@ export class OrganizationSubscriptionCloudComponent implements OnInit, OnDestroy
}
};
- discountPrice = (price: number) => {
+ discountPrice = (price: number, productId: string = null) => {
const discount =
- !!this.customerDiscount && this.customerDiscount.active
+ this.customerDiscount?.active &&
+ (!productId ||
+ !this.customerDiscount.appliesTo.length ||
+ this.customerDiscount.appliesTo.includes(productId))
? price * (this.customerDiscount.percentOff / 100)
: 0;
diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json
index 2fb5f002f7..419dcb605d 100644
--- a/apps/web/src/locales/en/messages.json
+++ b/apps/web/src/locales/en/messages.json
@@ -2531,6 +2531,15 @@
}
}
},
+ "trialSecretsManagerThankYou": {
+ "message": "Thanks for signing up for Bitwarden Secrets Manager for $PLAN$!",
+ "placeholders": {
+ "plan": {
+ "content": "$1",
+ "example": "Teams"
+ }
+ }
+ },
"trialPaidInfoMessage": {
"message": "Your $PLAN$ 7 day free trial will be converted to a paid subscription after 7 days.",
"placeholders": {
@@ -3471,7 +3480,7 @@
"message": "Set a seat limit for your subscription. Once this limit is reached, you will not be able to invite new members."
},
"limitSmSubscriptionDesc": {
- "message": "Set a seat limit for your Secrets Manger subscription. Once this limit is reached, you will not be able to invite new members."
+ "message": "Set a seat limit for your Secrets Manager subscription. Once this limit is reached, you will not be able to invite new members."
},
"maxSeatLimit": {
"message": "Seat Limit (optional)",
@@ -7234,6 +7243,15 @@
}
}
},
+ "startYour7DayFreeTrialOfBitwardenSecretsManagerFor": {
+ "message": "Start your 7-Day free trial of Bitwarden Secrets Manager for $ORG$",
+ "placeholders": {
+ "org": {
+ "content": "$1",
+ "example": "Organization name"
+ }
+ }
+ },
"next": {
"message": "Next"
},
@@ -7508,5 +7526,17 @@
},
"collectionEnhancementsLearnMore": {
"message": "Learn more about collection management"
+ },
+ "organizationInformation": {
+ "message": "Organization information"
+ },
+ "confirmationDetails": {
+ "message": "Confirmation details"
+ },
+ "smFreeTrialThankYou": {
+ "message": "Thank you for signing up for Bitwarden Secrets Manager!"
+ },
+ "smFreeTrialConfirmationEmail": {
+ "message": "We've sent a confirmation email to your email at "
}
}
diff --git a/clients.code-workspace b/clients.code-workspace
index 608f57096b..6263182b4d 100644
--- a/clients.code-workspace
+++ b/clients.code-workspace
@@ -2,47 +2,47 @@
"folders": [
{
"name": "root",
- "path": ".",
+ "path": "."
},
{
"name": "web vault",
- "path": "apps/web",
+ "path": "apps/web"
},
{
"name": "web vault (bit)",
- "path": "bitwarden_license/bit-web",
+ "path": "bitwarden_license/bit-web"
},
{
"name": "cli",
- "path": "apps/cli",
+ "path": "apps/cli"
},
{
"name": "desktop",
- "path": "apps/desktop",
+ "path": "apps/desktop"
},
{
"name": "browser",
- "path": "apps/browser",
+ "path": "apps/browser"
},
{
"name": "libs",
- "path": "libs",
- },
+ "path": "libs"
+ }
],
"settings": {
"eslint.options": {
"overrideConfig": {
"parserOptions": {
- "project": ["${workspaceFolder}/tsconfig.eslint.json"],
- },
- },
+ "project": ["${workspaceFolder}/tsconfig.eslint.json"]
+ }
+ }
},
"debug.javascript.terminalOptions": {
"sourceMapPathOverrides": {
"webpack:///./~/*": "${workspaceFolder:root}/node_modules/*",
"webpack://?:*/*": "${workspaceFolder}/*",
- "webpack://@bitwarden/cli/*": "${workspaceFolder}/*",
- },
+ "webpack://@bitwarden/cli/*": "${workspaceFolder}/*"
+ }
},
"jest.disabledWorkspaceFolders": [
"browser",
@@ -56,14 +56,14 @@
"jest.jestCommandLine": "npx jest",
"angular.enable-strict-mode-prompt": false,
"typescript.preferences.importModuleSpecifier": "project-relative",
- "javascript.preferences.importModuleSpecifier": "project-relative",
+ "javascript.preferences.importModuleSpecifier": "project-relative"
},
"extensions": {
"recommendations": [
"orta.vscode-jest",
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
- "Angular.ng-template",
- ],
- },
+ "Angular.ng-template"
+ ]
+ }
}
diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts
index f75ae1ea12..75a39a8aae 100644
--- a/libs/angular/src/services/jslib-services.module.ts
+++ b/libs/angular/src/services/jslib-services.module.ts
@@ -76,7 +76,9 @@ import { WebAuthnLoginApiService } from "@bitwarden/common/auth/services/webauth
import { WebAuthnLoginPrfCryptoService } from "@bitwarden/common/auth/services/webauthn-login/webauthn-login-prf-crypto.service";
import { WebAuthnLoginService } from "@bitwarden/common/auth/services/webauthn-login/webauthn-login.service";
import { BillingBannerServiceAbstraction } from "@bitwarden/common/billing/abstractions/billing-banner.service.abstraction";
+import { OrganizationBillingServiceAbstraction } from "@bitwarden/common/billing/abstractions/organization-billing.service";
import { BillingBannerService } from "@bitwarden/common/billing/services/billing-banner.service";
+import { OrganizationBillingService } from "@bitwarden/common/billing/services/organization-billing.service";
import { AppIdService as AppIdServiceAbstraction } from "@bitwarden/common/platform/abstractions/app-id.service";
import { BroadcasterService as BroadcasterServiceAbstraction } from "@bitwarden/common/platform/abstractions/broadcaster.service";
import { ConfigApiServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config-api.service.abstraction";
@@ -864,6 +866,16 @@ import { ModalService } from "./modal.service";
useClass: BillingBannerService,
deps: [StateProvider],
},
+ {
+ provide: OrganizationBillingServiceAbstraction,
+ useClass: OrganizationBillingService,
+ deps: [
+ CryptoServiceAbstraction,
+ EncryptService,
+ I18nServiceAbstraction,
+ OrganizationApiServiceAbstraction,
+ ],
+ },
],
})
export class JslibServicesModule {}
diff --git a/libs/common/src/admin-console/models/request/organization-create.request.ts b/libs/common/src/admin-console/models/request/organization-create.request.ts
index 729cf45365..9c7d620d29 100644
--- a/libs/common/src/admin-console/models/request/organization-create.request.ts
+++ b/libs/common/src/admin-console/models/request/organization-create.request.ts
@@ -27,4 +27,5 @@ export class OrganizationCreateRequest {
useSecretsManager: boolean;
additionalSmSeats: number;
additionalServiceAccounts: number;
+ isFromSecretsManagerTrial: boolean;
}
diff --git a/libs/common/src/billing/abstractions/organization-billing.service.ts b/libs/common/src/billing/abstractions/organization-billing.service.ts
new file mode 100644
index 0000000000..8e2bdc2efe
--- /dev/null
+++ b/libs/common/src/billing/abstractions/organization-billing.service.ts
@@ -0,0 +1,45 @@
+import { OrganizationResponse } from "../../admin-console/models/response/organization.response";
+import { PaymentMethodType, PlanType } from "../enums";
+
+export type OrganizationInformation = {
+ name: string;
+ billingEmail: string;
+ businessName?: string;
+};
+
+export type PlanInformation = {
+ type: PlanType;
+ passwordManagerSeats?: number;
+ subscribeToSecretsManager?: boolean;
+ isFromSecretsManagerTrial?: boolean;
+ secretsManagerSeats?: number;
+ secretsManagerServiceAccounts?: number;
+ storage?: number;
+};
+
+export type BillingInformation = {
+ postalCode: string;
+ country: string;
+ taxId?: string;
+ addressLine1?: string;
+ addressLine2?: string;
+ city?: string;
+ state?: string;
+};
+
+export type PaymentInformation = {
+ paymentMethod: [string, PaymentMethodType];
+ billing: BillingInformation;
+};
+
+export type SubscriptionInformation = {
+ organization: OrganizationInformation;
+ plan?: PlanInformation;
+ payment?: PaymentInformation;
+};
+
+export abstract class OrganizationBillingServiceAbstraction {
+ purchaseSubscription: (subscription: SubscriptionInformation) => Promise;
+
+ startFree: (subscription: SubscriptionInformation) => Promise;
+}
diff --git a/libs/common/src/billing/models/response/organization-subscription.response.ts b/libs/common/src/billing/models/response/organization-subscription.response.ts
index 404540c616..c3704f6023 100644
--- a/libs/common/src/billing/models/response/organization-subscription.response.ts
+++ b/libs/common/src/billing/models/response/organization-subscription.response.ts
@@ -40,17 +40,13 @@ export class BillingCustomerDiscount extends BaseResponse {
id: string;
active: boolean;
percentOff?: number;
+ appliesTo: string[];
constructor(response: any) {
super(response);
this.id = this.getResponseProperty("Id");
this.active = this.getResponseProperty("Active");
this.percentOff = this.getResponseProperty("PercentOff");
+ this.appliesTo = this.getResponseProperty("AppliesTo");
}
-
- discountPrice = (price: number) => {
- const discount = this !== null && this.active ? price * (this.percentOff / 100) : 0;
-
- return price - discount;
- };
}
diff --git a/libs/common/src/billing/models/response/subscription.response.ts b/libs/common/src/billing/models/response/subscription.response.ts
index b5286ead42..0a2cb2290e 100644
--- a/libs/common/src/billing/models/response/subscription.response.ts
+++ b/libs/common/src/billing/models/response/subscription.response.ts
@@ -39,7 +39,7 @@ export class BillingSubscriptionResponse extends BaseResponse {
constructor(response: any) {
super(response);
- this.trialEndDate = this.getResponseProperty("TrialStartDate");
+ this.trialStartDate = this.getResponseProperty("TrialStartDate");
this.trialEndDate = this.getResponseProperty("TrialEndDate");
this.periodStartDate = this.getResponseProperty("PeriodStartDate");
this.periodEndDate = this.getResponseProperty("PeriodEndDate");
@@ -55,6 +55,7 @@ export class BillingSubscriptionResponse extends BaseResponse {
}
export class BillingSubscriptionItemResponse extends BaseResponse {
+ productId: string;
name: string;
amount: number;
quantity: number;
@@ -65,6 +66,7 @@ export class BillingSubscriptionItemResponse extends BaseResponse {
constructor(response: any) {
super(response);
+ this.productId = this.getResponseProperty("ProductId");
this.name = this.getResponseProperty("Name");
this.amount = this.getResponseProperty("Amount");
this.quantity = this.getResponseProperty("Quantity");
diff --git a/libs/common/src/billing/services/organization-billing.service.ts b/libs/common/src/billing/services/organization-billing.service.ts
new file mode 100644
index 0000000000..3e5d67ade6
--- /dev/null
+++ b/libs/common/src/billing/services/organization-billing.service.ts
@@ -0,0 +1,143 @@
+import { OrganizationApiServiceAbstraction as OrganizationApiService } from "../../admin-console/abstractions/organization/organization-api.service.abstraction";
+import { OrganizationCreateRequest } from "../../admin-console/models/request/organization-create.request";
+import { OrganizationKeysRequest } from "../../admin-console/models/request/organization-keys.request";
+import { OrganizationResponse } from "../../admin-console/models/response/organization.response";
+import { CryptoService } from "../../platform/abstractions/crypto.service";
+import { EncryptService } from "../../platform/abstractions/encrypt.service";
+import { I18nService } from "../../platform/abstractions/i18n.service";
+import { EncString } from "../../platform/models/domain/enc-string";
+import { OrgKey } from "../../types/key";
+import {
+ OrganizationBillingServiceAbstraction,
+ OrganizationInformation,
+ PaymentInformation,
+ PlanInformation,
+ SubscriptionInformation,
+} from "../abstractions/organization-billing.service";
+import { PlanType } from "../enums";
+
+interface OrganizationKeys {
+ encryptedKey: EncString;
+ publicKey: string;
+ encryptedPrivateKey: EncString;
+ encryptedCollectionName: EncString;
+}
+
+export class OrganizationBillingService implements OrganizationBillingServiceAbstraction {
+ constructor(
+ private cryptoService: CryptoService,
+ private encryptService: EncryptService,
+ private i18nService: I18nService,
+ private organizationApiService: OrganizationApiService,
+ ) {}
+
+ async purchaseSubscription(subscription: SubscriptionInformation): Promise {
+ const request = new OrganizationCreateRequest();
+
+ const organizationKeys = await this.makeOrganizationKeys();
+
+ this.setOrganizationKeys(request, organizationKeys);
+
+ this.setOrganizationInformation(request, subscription.organization);
+
+ this.setPlanInformation(request, subscription.plan);
+
+ this.setPaymentInformation(request, subscription.payment);
+
+ return await this.organizationApiService.create(request);
+ }
+
+ async startFree(subscription: SubscriptionInformation): Promise {
+ const request = new OrganizationCreateRequest();
+
+ const organizationKeys = await this.makeOrganizationKeys();
+
+ this.setOrganizationKeys(request, organizationKeys);
+
+ this.setOrganizationInformation(request, subscription.organization);
+
+ this.setPlanInformation(request, subscription.plan);
+
+ return await this.organizationApiService.create(request);
+ }
+
+ private async makeOrganizationKeys(): Promise {
+ const [encryptedKey, key] = await this.cryptoService.makeOrgKey();
+ const [publicKey, encryptedPrivateKey] = await this.cryptoService.makeKeyPair(key);
+ const encryptedCollectionName = await this.encryptService.encrypt(
+ this.i18nService.t("defaultCollection"),
+ key,
+ );
+ return {
+ encryptedKey,
+ publicKey,
+ encryptedPrivateKey,
+ encryptedCollectionName,
+ };
+ }
+
+ private setOrganizationInformation(
+ request: OrganizationCreateRequest,
+ information: OrganizationInformation,
+ ): void {
+ request.name = information.name;
+ request.businessName = information.businessName;
+ request.billingEmail = information.billingEmail;
+ }
+
+ private setOrganizationKeys(request: OrganizationCreateRequest, keys: OrganizationKeys): void {
+ request.key = keys.encryptedKey.encryptedString;
+ request.keys = new OrganizationKeysRequest(
+ keys.publicKey,
+ keys.encryptedPrivateKey.encryptedString,
+ );
+ request.collectionName = keys.encryptedCollectionName.encryptedString;
+ }
+
+ private setPaymentInformation(
+ request: OrganizationCreateRequest,
+ information: PaymentInformation,
+ ) {
+ const [paymentToken, paymentMethodType] = information.paymentMethod;
+ request.paymentToken = paymentToken;
+ request.paymentMethodType = paymentMethodType;
+
+ const billingInformation = information.billing;
+ request.billingAddressPostalCode = billingInformation.postalCode;
+ request.billingAddressCountry = billingInformation.country;
+
+ if (billingInformation.taxId) {
+ request.taxIdNumber = billingInformation.taxId;
+ request.billingAddressLine1 = billingInformation.addressLine1;
+ request.billingAddressLine2 = billingInformation.addressLine2;
+ request.billingAddressCity = billingInformation.city;
+ request.billingAddressState = billingInformation.state;
+ }
+ }
+
+ private setPlanInformation(
+ request: OrganizationCreateRequest,
+ information: PlanInformation,
+ ): void {
+ request.planType = information.type;
+
+ if (request.planType === PlanType.Free) {
+ request.useSecretsManager = information.subscribeToSecretsManager;
+ request.isFromSecretsManagerTrial = information.isFromSecretsManagerTrial;
+ return;
+ }
+
+ request.additionalSeats = information.passwordManagerSeats;
+
+ if (information.subscribeToSecretsManager) {
+ request.useSecretsManager = true;
+ request.isFromSecretsManagerTrial = information.isFromSecretsManagerTrial;
+ request.additionalSmSeats = information.secretsManagerSeats;
+ request.additionalServiceAccounts = information.secretsManagerServiceAccounts;
+ }
+
+ if (information.storage) {
+ request.additionalStorageGb = information.storage;
+ }
+ }
+}