diff --git a/src/Core/Models/Api/Request/Organizations/OrganizationCreateRequestModel.cs b/src/Core/Models/Api/Request/Organizations/OrganizationCreateRequestModel.cs index 5504333d05..3d6b6cc7b3 100644 --- a/src/Core/Models/Api/Request/Organizations/OrganizationCreateRequestModel.cs +++ b/src/Core/Models/Api/Request/Organizations/OrganizationCreateRequestModel.cs @@ -26,6 +26,7 @@ namespace Bit.Core.Models.Api public short AdditionalSeats { get; set; } [Range(0, 99)] public short? AdditionalStorageGb { get; set; } + public bool PremiumAccessAddon { get; set; } [EncryptedString] [EncryptedStringLength(1000)] public string CollectionName { get; set; } @@ -42,6 +43,7 @@ namespace Bit.Core.Models.Api PaymentToken = PaymentToken, AdditionalSeats = AdditionalSeats, AdditionalStorageGb = AdditionalStorageGb.GetValueOrDefault(0), + PremiumAccessAddon = PremiumAccessAddon, BillingEmail = BillingEmail, BusinessName = BusinessName, BusinessCountry = Country, diff --git a/src/Core/Models/Business/OrganizationSignup.cs b/src/Core/Models/Business/OrganizationSignup.cs index eca1d04d27..463b58e005 100644 --- a/src/Core/Models/Business/OrganizationSignup.cs +++ b/src/Core/Models/Business/OrganizationSignup.cs @@ -13,6 +13,7 @@ namespace Bit.Core.Models.Business public Enums.PlanType Plan { get; set; } public short AdditionalSeats { get; set; } public short AdditionalStorageGb { get; set; } + public bool PremiumAccessAddon { get; set; } public string PaymentToken { get; set; } public string CollectionName { get; set; } } diff --git a/src/Core/Models/StaticStore/Plan.cs b/src/Core/Models/StaticStore/Plan.cs index e76c5a0d43..b11a9f6b26 100644 --- a/src/Core/Models/StaticStore/Plan.cs +++ b/src/Core/Models/StaticStore/Plan.cs @@ -7,11 +7,13 @@ namespace Bit.Core.Models.StaticStore public string Name { get; set; } public string StripePlanId { get; set; } public string StripeSeatPlanId { get; set; } - public string StripStoragePlanId { get; set; } + public string StripeStoragePlanId { get; set; } + public string StripePremiumAccessPlanId { get; set; } public PlanType Type { get; set; } public short BaseSeats { get; set; } public bool CanBuyAdditionalSeats { get; set; } public short? MaxAdditionalSeats { get; set; } + public bool CanBuyPremiumAccessAddon { get; set; } public bool UseGroups { get; set; } public bool UseDirectory { get; set; } public bool UseEvents { get; set; } diff --git a/src/Core/Services/Implementations/OrganizationService.cs b/src/Core/Services/Implementations/OrganizationService.cs index 505398a414..6a122c6b36 100644 --- a/src/Core/Services/Implementations/OrganizationService.cs +++ b/src/Core/Services/Implementations/OrganizationService.cs @@ -265,7 +265,7 @@ namespace Bit.Core.Services } await BillingHelpers.AdjustStorageAsync(_stripePaymentService, organization, storageAdjustmentGb, - plan.StripStoragePlanId); + plan.StripeStoragePlanId); await ReplaceAndUpdateCache(organization); } @@ -424,6 +424,11 @@ namespace Bit.Core.Services throw new BadRequestException("Plan does not allow additional storage."); } + if(!plan.CanBuyPremiumAccessAddon && signup.PremiumAccessAddon) + { + throw new BadRequestException("This plan does not allow you to buy the premium access addon."); + } + if(plan.BaseSeats + signup.AdditionalSeats <= 0) { throw new BadRequestException("You do not have any seats!"); @@ -499,11 +504,20 @@ namespace Bit.Core.Services { subCreateOptions.Items.Add(new StripeSubscriptionItemOption { - PlanId = plan.StripStoragePlanId, + PlanId = plan.StripeStoragePlanId, Quantity = signup.AdditionalStorageGb }); } + if(signup.PremiumAccessAddon && plan.StripePremiumAccessPlanId != null) + { + subCreateOptions.Items.Add(new StripeSubscriptionItemOption + { + PlanId = plan.StripePremiumAccessPlanId, + Quantity = 1 + }); + } + try { subscription = await subscriptionService.CreateAsync(subCreateOptions); @@ -537,7 +551,7 @@ namespace Bit.Core.Services UseTotp = plan.UseTotp, Use2fa = plan.Use2fa, SelfHost = plan.SelfHost, - UsersGetPremium = plan.UsersGetPremium, + UsersGetPremium = plan.UsersGetPremium || signup.PremiumAccessAddon, Plan = plan.Name, Gateway = plan.Type == PlanType.Free ? null : (GatewayType?)GatewayType.Stripe, GatewayCustomerId = customer?.Id, diff --git a/src/Core/Utilities/StaticStore.cs b/src/Core/Utilities/StaticStore.cs index b68ff8c5a8..0374a710ac 100644 --- a/src/Core/Utilities/StaticStore.cs +++ b/src/Core/Utilities/StaticStore.cs @@ -108,9 +108,11 @@ namespace Bit.Core.Utilities BaseSeats = 5, BasePrice = 12, CanBuyAdditionalSeats = false, + CanBuyPremiumAccessAddon = true, Name = "Families", StripePlanId = "personal-org-annually", - StripStoragePlanId = "storage-gb-annually", + StripeStoragePlanId = "storage-gb-annually", + StripePremiumAccessPlanId = "personal-org-premium-access-annually", UpgradeSortOrder = 1, TrialPeriodDays = 7, UseTotp = true, @@ -127,7 +129,7 @@ namespace Bit.Core.Utilities Name = "Teams (Monthly)", StripePlanId = "teams-org-monthly", StripeSeatPlanId = "teams-org-seat-monthly", - StripStoragePlanId = "storage-gb-monthly", + StripeStoragePlanId = "storage-gb-monthly", UpgradeSortOrder = 2, TrialPeriodDays = 7, UseTotp = true, @@ -143,7 +145,7 @@ namespace Bit.Core.Utilities Name = "Teams (Annually)", StripePlanId = "teams-org-annually", StripeSeatPlanId = "teams-org-seat-annually", - StripStoragePlanId = "storage-gb-annually", + StripeStoragePlanId = "storage-gb-annually", UpgradeSortOrder = 2, TrialPeriodDays = 7, UseTotp = true, @@ -159,7 +161,7 @@ namespace Bit.Core.Utilities Name = "Enterprise (Monthly)", StripePlanId = null, StripeSeatPlanId = "enterprise-org-seat-monthly", - StripStoragePlanId = "storage-gb-monthly", + StripeStoragePlanId = "storage-gb-monthly", UpgradeSortOrder = 3, TrialPeriodDays = 7, UseGroups = true, @@ -181,7 +183,7 @@ namespace Bit.Core.Utilities Name = "Enterprise (Annually)", StripePlanId = null, StripeSeatPlanId = "enterprise-org-seat-annually", - StripStoragePlanId = "storage-gb-annually", + StripeStoragePlanId = "storage-gb-annually", UpgradeSortOrder = 3, TrialPeriodDays = 7, UseGroups = true,