diff --git a/src/Api/Billing/Controllers/AccountsController.cs b/src/Api/Billing/Controllers/AccountsController.cs index dec28f552e..1a10b2dcf7 100644 --- a/src/Api/Billing/Controllers/AccountsController.cs +++ b/src/Api/Billing/Controllers/AccountsController.cs @@ -3,10 +3,13 @@ using Bit.Api.Models.Request.Accounts; using Bit.Api.Models.Response; using Bit.Api.Utilities; using Bit.Core; +using Bit.Core.Auth.UserFeatures.TwoFactorAuth.Interfaces; using Bit.Core.Billing.Models; using Bit.Core.Billing.Models.Business; using Bit.Core.Billing.Services; using Bit.Core.Exceptions; +using Bit.Core.KeyManagement.Queries.Interfaces; +using Bit.Core.Models.Business; using Bit.Core.Services; using Bit.Core.Settings; using Bit.Core.Utilities; @@ -19,9 +22,59 @@ namespace Bit.Api.Billing.Controllers; [Authorize("Application")] public class AccountsController( IUserService userService, + ITwoFactorIsEnabledQuery twoFactorIsEnabledQuery, + IUserAccountKeysQuery userAccountKeysQuery, IFeatureService featureService, ILicensingService licensingService) : Controller { + // TODO: Remove when pm-24996-implement-upgrade-from-free-dialog and pm-24033-updat-premium-subscription-page are removed + [HttpPost("premium")] + public async Task PostPremiumAsync( + PremiumRequestModel model, + [FromServices] GlobalSettings globalSettings) + { + var user = await userService.GetUserByPrincipalAsync(User); + if (user == null) + { + throw new UnauthorizedAccessException(); + } + + var valid = model.Validate(globalSettings); + UserLicense? license = null; + if (valid && globalSettings.SelfHosted) + { + license = await ApiHelpers.ReadJsonFileFromBody(HttpContext, model.License); + } + + if (!valid && !globalSettings.SelfHosted && string.IsNullOrWhiteSpace(model.Country)) + { + throw new BadRequestException("Country is required."); + } + + if (!valid || (globalSettings.SelfHosted && license == null)) + { + throw new BadRequestException("Invalid license."); + } + + var result = await userService.SignUpPremiumAsync(user, model.PaymentToken, + model.PaymentMethodType!.Value, model.AdditionalStorageGb.GetValueOrDefault(0), license, + new TaxInfo { BillingAddressCountry = model.Country, BillingAddressPostalCode = model.PostalCode }); + + var userTwoFactorEnabled = await twoFactorIsEnabledQuery.TwoFactorIsEnabledAsync(user); + var userHasPremiumFromOrganization = await userService.HasPremiumFromOrganization(user); + var organizationIdsClaimingActiveUser = await GetOrganizationIdsClaimingUserAsync(user.Id); + var accountKeys = await userAccountKeysQuery.Run(user); + + var profile = new ProfileResponseModel(user, accountKeys, null, null, null, userTwoFactorEnabled, + userHasPremiumFromOrganization, organizationIdsClaimingActiveUser); + return new PaymentResponseModel + { + UserProfile = profile, + PaymentIntentClientSecret = result.Item2, + Success = result.Item1 + }; + } + // TODO: Migrate to Query / AccountBillingVNextController as part of Premium -> Organization upgrade work. [HttpGet("subscription")] public async Task GetSubscriptionAsync(