diff --git a/model/hosted_customer.go b/model/hosted_customer.go index 4f1917bdaf..d2856eab45 100644 --- a/model/hosted_customer.go +++ b/model/hosted_customer.go @@ -32,6 +32,11 @@ type SelfHostedConfirmPaymentMethodRequest struct { Subscription CreateSubscriptionRequest `json:"subscription"` } +type SelfHostedExpansionConfirmPaymentMethodRequest struct { + StripeSetupIntentID string `json:"stripe_setup_intent_id"` + ExpandRequest SelfHostedExpansionRequest `json:"expand_request"` +} + // SelfHostedSignupPaymentResponse contains feels needed for self hosted signup to confirm payment and receive license. type SelfHostedSignupCustomerResponse struct { CustomerId string `json:"customer_id"` @@ -58,3 +63,8 @@ type SelfHostedBillingAccessRequest struct { type SelfHostedBillingAccessResponse struct { Token string `json:"token"` } + +type SelfHostedExpansionRequest struct { + Seats int `json:"seats"` + LicenseId string `json:"license_id"` +} diff --git a/server/channels/api4/hosted_customer.go b/server/channels/api4/hosted_customer.go index 4792969c15..3662582891 100644 --- a/server/channels/api4/hosted_customer.go +++ b/server/channels/api4/hosted_customer.go @@ -65,9 +65,18 @@ func checkSelfHostedPurchaseEnabled(c *Context) bool { return enabled != nil && *enabled } +func checkSelfHostedExpansionEnabled(c *Context) bool { + config := c.App.Config() + if config == nil { + return false + } + enabled := config.ServiceSettings.SelfHostedExpansion + return enabled != nil && *enabled +} + func selfHostedBootstrap(c *Context, w http.ResponseWriter, r *http.Request) { const where = "Api4.selfHostedBootstrap" - if !checkSelfHostedPurchaseEnabled(c) { + if !checkSelfHostedPurchaseEnabled(c) && !checkSelfHostedExpansionEnabled(c) { c.Err = model.NewAppError(where, "api.cloud.app_error", nil, "", http.StatusNotImplemented) return } @@ -151,25 +160,40 @@ func selfHostedConfirm(c *Context, w http.ResponseWriter, r *http.Request) { return } + expand := r.URL.Query().Get("expand") == "true" + bodyBytes, err := io.ReadAll(r.Body) if err != nil { c.Err = model.NewAppError(where, "api.cloud.app_error", nil, "", http.StatusBadRequest).Wrap(err) return } - var confirm model.SelfHostedConfirmPaymentMethodRequest - err = json.Unmarshal(bodyBytes, &confirm) - if err != nil { - c.Err = model.NewAppError(where, "api.cloud.request_error", nil, "", http.StatusBadRequest).Wrap(err) - return - } - user, userErr := c.App.GetUser(c.AppContext.Session().UserId) if userErr != nil { c.Err = userErr return } - confirmResponse, err := c.App.Cloud().ConfirmSelfHostedSignup(confirm, user.Email) + + var confirmResponse *model.SelfHostedSignupConfirmResponse + if expand { + var confirm model.SelfHostedExpansionConfirmPaymentMethodRequest + err = json.Unmarshal(bodyBytes, &confirm) + if err != nil { + c.Err = model.NewAppError(where, "api.cloud.request_error", nil, "", http.StatusBadRequest).Wrap(err) + return + } + + confirmResponse, err = c.App.Cloud().ConfirmSelfHostedExpansion(confirm, user.Email) + } else { + var confirm model.SelfHostedConfirmPaymentMethodRequest + err = json.Unmarshal(bodyBytes, &confirm) + if err != nil { + c.Err = model.NewAppError(where, "api.cloud.request_error", nil, "", http.StatusBadRequest).Wrap(err) + return + } + + confirmResponse, err = c.App.Cloud().ConfirmSelfHostedSignup(confirm, user.Email) + } if err != nil { if confirmResponse != nil { c.App.NotifySelfHostedSignupProgress(confirmResponse.Progress, user.Id) diff --git a/server/channels/einterfaces/cloud.go b/server/channels/einterfaces/cloud.go index b5d6a75b68..8d92474cc8 100644 --- a/server/channels/einterfaces/cloud.go +++ b/server/channels/einterfaces/cloud.go @@ -37,6 +37,7 @@ type CloudInterface interface { BootstrapSelfHostedSignup(req model.BootstrapSelfHostedSignupRequest) (*model.BootstrapSelfHostedSignupResponse, error) CreateCustomerSelfHostedSignup(req model.SelfHostedCustomerForm, requesterEmail string) (*model.SelfHostedSignupCustomerResponse, error) ConfirmSelfHostedSignup(req model.SelfHostedConfirmPaymentMethodRequest, requesterEmail string) (*model.SelfHostedSignupConfirmResponse, error) + ConfirmSelfHostedExpansion(req model.SelfHostedExpansionConfirmPaymentMethodRequest, requesterEmail string) (*model.SelfHostedSignupConfirmResponse, error) ConfirmSelfHostedSignupLicenseApplication() error GetSelfHostedInvoices() ([]*model.Invoice, error) GetSelfHostedInvoicePDF(invoiceID string) ([]byte, string, error)