mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-04 08:26:10 +00:00
Add forwarding usedSeats and subscription quantity to license server on org member add/delete
This commit is contained in:
@@ -135,6 +135,7 @@ export const inviteUserToOrganization = async (req: Request, res: Response) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!inviteeMembershipOrg) {
|
if (!inviteeMembershipOrg) {
|
||||||
|
|
||||||
await new MembershipOrg({
|
await new MembershipOrg({
|
||||||
user: invitee,
|
user: invitee,
|
||||||
inviteEmail: inviteeEmail,
|
inviteEmail: inviteeEmail,
|
||||||
@@ -246,6 +247,10 @@ export const verifyUserToOrganization = async (req: Request, res: Response) => {
|
|||||||
// membership can be approved and redirected to login/dashboard
|
// membership can be approved and redirected to login/dashboard
|
||||||
membershipOrg.status = ACCEPTED;
|
membershipOrg.status = ACCEPTED;
|
||||||
await membershipOrg.save();
|
await membershipOrg.save();
|
||||||
|
|
||||||
|
await updateSubscriptionOrgQuantity({
|
||||||
|
organizationId
|
||||||
|
});
|
||||||
|
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
message: 'Successfully verified email',
|
message: 'Successfully verified email',
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { issueAuthTokens } from '../../helpers/auth';
|
|||||||
import { INVITED, ACCEPTED } from '../../variables';
|
import { INVITED, ACCEPTED } from '../../variables';
|
||||||
import { standardRequest } from '../../config/request';
|
import { standardRequest } from '../../config/request';
|
||||||
import { getLoopsApiKey, getHttpsEnabled } from '../../config';
|
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
|
* 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
|
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
|
// update organization membership statuses that are
|
||||||
// invited to completed with user attached
|
// invited to completed with user attached
|
||||||
await MembershipOrg.updateMany(
|
await MembershipOrg.updateMany(
|
||||||
@@ -206,9 +220,20 @@ export const completeAccountInvite = async (req: Request, res: Response) => {
|
|||||||
|
|
||||||
if (!user)
|
if (!user)
|
||||||
throw new Error('Failed to complete account for non-existent user');
|
throw new Error('Failed to complete account for non-existent user');
|
||||||
|
|
||||||
// update organization membership statuses that are
|
// update organization membership statuses that are
|
||||||
// invited to completed with user attached
|
// 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(
|
await MembershipOrg.updateMany(
|
||||||
{
|
{
|
||||||
inviteEmail: email,
|
inviteEmail: email,
|
||||||
|
|||||||
@@ -29,6 +29,16 @@ import {
|
|||||||
} from "../utils/errors";
|
} from "../utils/errors";
|
||||||
import { validateUserClientForOrganization } from "../helpers/user";
|
import { validateUserClientForOrganization } from "../helpers/user";
|
||||||
import { validateServiceAccountClientForOrganization } from "../helpers/serviceAccount";
|
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]
|
* Validate accepted clients for organization with id [organizationId]
|
||||||
@@ -228,30 +238,35 @@ const updateSubscriptionOrgQuantity = async ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (organization && organization.customerId) {
|
if (organization && organization.customerId) {
|
||||||
const quantity = await MembershipOrg.countDocuments({
|
if (EELicenseService.instanceType === 'cloud') {
|
||||||
organization: organizationId,
|
// instance of Infisical is a cloud instance
|
||||||
status: ACCEPTED,
|
const quantity = await MembershipOrg.countDocuments({
|
||||||
});
|
organization: new Types.ObjectId(organizationId),
|
||||||
|
status: ACCEPTED,
|
||||||
const stripe = new Stripe(await getStripeSecretKey(), {
|
});
|
||||||
apiVersion: "2022-08-01",
|
|
||||||
});
|
await licenseServerKeyRequest.patch(
|
||||||
|
`${await getLicenseServerUrl()}/api/license-server/v1/customers/${organization.customerId}/cloud-plan`,
|
||||||
const subscription = (
|
|
||||||
await stripe.subscriptions.list({
|
|
||||||
customer: organization.customerId,
|
|
||||||
})
|
|
||||||
).data[0];
|
|
||||||
|
|
||||||
stripeSubscription = await stripe.subscriptions.update(subscription.id, {
|
|
||||||
items: [
|
|
||||||
{
|
{
|
||||||
id: subscription.items.data[0].id,
|
quantity
|
||||||
price: subscription.items.data[0].price.id,
|
}
|
||||||
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;
|
return stripeSubscription;
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import { Request, Response, NextFunction } from 'express';
|
import { Request, Response, NextFunction } from 'express';
|
||||||
import { Types } from 'mongoose';
|
import { Types } from 'mongoose';
|
||||||
import { validateMembership } from '../helpers/membership';
|
|
||||||
import { validateClientForWorkspace } from '../helpers/workspace';
|
import { validateClientForWorkspace } from '../helpers/workspace';
|
||||||
import { UnauthorizedRequestError } from '../utils/errors';
|
|
||||||
|
|
||||||
type req = 'params' | 'body' | 'query';
|
type req = 'params' | 'body' | 'query';
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user