diff --git a/backend/src/controllers/v1/membershipOrgController.ts b/backend/src/controllers/v1/membershipOrgController.ts index e5714516e..60cdc9691 100644 --- a/backend/src/controllers/v1/membershipOrgController.ts +++ b/backend/src/controllers/v1/membershipOrgController.ts @@ -135,6 +135,7 @@ export const inviteUserToOrganization = async (req: Request, res: Response) => { } if (!inviteeMembershipOrg) { + await new MembershipOrg({ user: invitee, inviteEmail: inviteeEmail, @@ -246,6 +247,10 @@ export const verifyUserToOrganization = async (req: Request, res: Response) => { // membership can be approved and redirected to login/dashboard membershipOrg.status = ACCEPTED; await membershipOrg.save(); + + await updateSubscriptionOrgQuantity({ + organizationId + }); return res.status(200).send({ message: 'Successfully verified email', diff --git a/backend/src/controllers/v2/signupController.ts b/backend/src/controllers/v2/signupController.ts index 28d40403c..d9e9a0447 100644 --- a/backend/src/controllers/v2/signupController.ts +++ b/backend/src/controllers/v2/signupController.ts @@ -9,6 +9,7 @@ import { issueAuthTokens } from '../../helpers/auth'; import { INVITED, ACCEPTED } from '../../variables'; import { standardRequest } from '../../config/request'; import { getLoopsApiKey, getHttpsEnabled } from '../../config'; +import { updateSubscriptionOrgQuantity } from '../../helpers/organization'; /** * Complete setting up user by adding their personal and auth information as part of the @@ -87,6 +88,19 @@ export const completeAccountSignup = async (req: Request, res: Response) => { user }); + // update organization membership statuses that are + // invited to completed with user attached + const membershipsToUpdate = await MembershipOrg.find({ + inviteEmail: email, + status: INVITED + }); + + membershipsToUpdate.forEach(async (membership) => { + await updateSubscriptionOrgQuantity({ + organizationId: membership.organization.toString() + }); + }); + // update organization membership statuses that are // invited to completed with user attached await MembershipOrg.updateMany( @@ -206,9 +220,20 @@ export const completeAccountInvite = async (req: Request, res: Response) => { if (!user) throw new Error('Failed to complete account for non-existent user'); - + // update organization membership statuses that are // invited to completed with user attached + const membershipsToUpdate = await MembershipOrg.find({ + inviteEmail: email, + status: INVITED + }); + + membershipsToUpdate.forEach(async (membership) => { + await updateSubscriptionOrgQuantity({ + organizationId: membership.organization.toString() + }); + }); + await MembershipOrg.updateMany( { inviteEmail: email, diff --git a/backend/src/helpers/organization.ts b/backend/src/helpers/organization.ts index 9e67ebb00..43b1bea83 100644 --- a/backend/src/helpers/organization.ts +++ b/backend/src/helpers/organization.ts @@ -29,6 +29,16 @@ import { } from "../utils/errors"; import { validateUserClientForOrganization } from "../helpers/user"; import { validateServiceAccountClientForOrganization } from "../helpers/serviceAccount"; +import { + EELicenseService +} from '../ee/services'; +import { + getLicenseServerUrl +} from '../config'; +import { + licenseServerKeyRequest, + licenseKeyRequest +} from '../config/request'; /** * Validate accepted clients for organization with id [organizationId] @@ -228,30 +238,35 @@ const updateSubscriptionOrgQuantity = async ({ }); if (organization && organization.customerId) { - const quantity = await MembershipOrg.countDocuments({ - organization: organizationId, - status: ACCEPTED, - }); - - const stripe = new Stripe(await getStripeSecretKey(), { - apiVersion: "2022-08-01", - }); - - const subscription = ( - await stripe.subscriptions.list({ - customer: organization.customerId, - }) - ).data[0]; - - stripeSubscription = await stripe.subscriptions.update(subscription.id, { - items: [ + if (EELicenseService.instanceType === 'cloud') { + // instance of Infisical is a cloud instance + const quantity = await MembershipOrg.countDocuments({ + organization: new Types.ObjectId(organizationId), + status: ACCEPTED, + }); + + await licenseServerKeyRequest.patch( + `${await getLicenseServerUrl()}/api/license-server/v1/customers/${organization.customerId}/cloud-plan`, { - id: subscription.items.data[0].id, - price: subscription.items.data[0].price.id, - quantity, - }, - ], - }); + quantity + } + ); + } + + if (EELicenseService.instanceType === 'enterprise-self-hosted') { + // instance of Infisical is an enterprise self-hosted instance + + const usedSeats = await MembershipOrg.countDocuments({ + status: ACCEPTED + }); + + await licenseKeyRequest.patch( + `${await getLicenseServerUrl()}/api/license/v1/license`, + { + usedSeats + } + ); + } } return stripeSubscription; diff --git a/backend/src/middleware/requireWorkspaceAuth.ts b/backend/src/middleware/requireWorkspaceAuth.ts index e8b433cd5..7e97b2e32 100644 --- a/backend/src/middleware/requireWorkspaceAuth.ts +++ b/backend/src/middleware/requireWorkspaceAuth.ts @@ -1,8 +1,6 @@ import { Request, Response, NextFunction } from 'express'; import { Types } from 'mongoose'; -import { validateMembership } from '../helpers/membership'; import { validateClientForWorkspace } from '../helpers/workspace'; -import { UnauthorizedRequestError } from '../utils/errors'; type req = 'params' | 'body' | 'query';