mirror of
https://github.com/Infisical/infisical.git
synced 2026-01-09 23:48:05 -05:00
Finish removing Stripe from codebase
This commit is contained in:
@@ -61,13 +61,6 @@ SENTRY_DSN=
|
|||||||
# Ignore - Not applicable for self-hosted version
|
# Ignore - Not applicable for self-hosted version
|
||||||
POSTHOG_HOST=
|
POSTHOG_HOST=
|
||||||
POSTHOG_PROJECT_API_KEY=
|
POSTHOG_PROJECT_API_KEY=
|
||||||
STRIPE_SECRET_KEY=
|
|
||||||
STRIPE_PUBLISHABLE_KEY=
|
|
||||||
STRIPE_WEBHOOK_SECRET=
|
|
||||||
STRIPE_PRODUCT_STARTER=
|
|
||||||
STRIPE_PRODUCT_TEAM=
|
|
||||||
STRIPE_PRODUCT_PRO=
|
|
||||||
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=
|
|
||||||
|
|
||||||
CLIENT_ID_GOOGLE=
|
CLIENT_ID_GOOGLE=
|
||||||
CLIENT_SECRET_GOOGLE=
|
CLIENT_SECRET_GOOGLE=
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -2,6 +2,7 @@
|
|||||||
node_modules
|
node_modules
|
||||||
.env
|
.env
|
||||||
.env.dev
|
.env.dev
|
||||||
|
.env.gamma
|
||||||
.env.prod
|
.env.prod
|
||||||
.env.infisical
|
.env.infisical
|
||||||
|
|
||||||
|
|||||||
6
backend/environment.d.ts
vendored
6
backend/environment.d.ts
vendored
@@ -39,12 +39,6 @@ declare global {
|
|||||||
SMTP_PASSWORD: string;
|
SMTP_PASSWORD: string;
|
||||||
SMTP_FROM_ADDRESS: string;
|
SMTP_FROM_ADDRESS: string;
|
||||||
SMTP_FROM_NAME: string;
|
SMTP_FROM_NAME: string;
|
||||||
STRIPE_PRODUCT_STARTER: string;
|
|
||||||
STRIPE_PRODUCT_TEAM: string;
|
|
||||||
STRIPE_PRODUCT_PRO: string;
|
|
||||||
STRIPE_PUBLISHABLE_KEY: string;
|
|
||||||
STRIPE_SECRET_KEY: string;
|
|
||||||
STRIPE_WEBHOOK_SECRET: string;
|
|
||||||
TELEMETRY_ENABLED: string;
|
TELEMETRY_ENABLED: string;
|
||||||
LICENSE_KEY: string;
|
LICENSE_KEY: string;
|
||||||
}
|
}
|
||||||
|
|||||||
22
backend/package-lock.json
generated
22
backend/package-lock.json
generated
@@ -50,7 +50,6 @@
|
|||||||
"query-string": "^7.1.3",
|
"query-string": "^7.1.3",
|
||||||
"rate-limit-mongo": "^2.3.2",
|
"rate-limit-mongo": "^2.3.2",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"stripe": "^10.7.0",
|
|
||||||
"swagger-autogen": "^2.22.0",
|
"swagger-autogen": "^2.22.0",
|
||||||
"swagger-ui-express": "^4.6.2",
|
"swagger-ui-express": "^4.6.2",
|
||||||
"tweetnacl": "^1.0.3",
|
"tweetnacl": "^1.0.3",
|
||||||
@@ -11588,18 +11587,6 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/stripe": {
|
|
||||||
"version": "10.17.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/stripe/-/stripe-10.17.0.tgz",
|
|
||||||
"integrity": "sha512-JHV2KoL+nMQRXu3m9ervCZZvi4DDCJfzHUE6CmtJxR9TmizyYfrVuhGvnsZLLnheby9Qrnf4Hq6iOEcejGwnGQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"@types/node": ">=8.1.0",
|
|
||||||
"qs": "^6.11.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": "^8.1 || >=10.*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/strnum": {
|
"node_modules/strnum": {
|
||||||
"version": "1.0.5",
|
"version": "1.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz",
|
||||||
@@ -21096,15 +21083,6 @@
|
|||||||
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
|
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"stripe": {
|
|
||||||
"version": "10.17.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/stripe/-/stripe-10.17.0.tgz",
|
|
||||||
"integrity": "sha512-JHV2KoL+nMQRXu3m9ervCZZvi4DDCJfzHUE6CmtJxR9TmizyYfrVuhGvnsZLLnheby9Qrnf4Hq6iOEcejGwnGQ==",
|
|
||||||
"requires": {
|
|
||||||
"@types/node": ">=8.1.0",
|
|
||||||
"qs": "^6.11.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"strnum": {
|
"strnum": {
|
||||||
"version": "1.0.5",
|
"version": "1.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz",
|
||||||
|
|||||||
@@ -41,7 +41,6 @@
|
|||||||
"query-string": "^7.1.3",
|
"query-string": "^7.1.3",
|
||||||
"rate-limit-mongo": "^2.3.2",
|
"rate-limit-mongo": "^2.3.2",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"stripe": "^10.7.0",
|
|
||||||
"swagger-autogen": "^2.22.0",
|
"swagger-autogen": "^2.22.0",
|
||||||
"swagger-ui-express": "^4.6.2",
|
"swagger-ui-express": "^4.6.2",
|
||||||
"tweetnacl": "^1.0.3",
|
"tweetnacl": "^1.0.3",
|
||||||
|
|||||||
@@ -67,14 +67,6 @@ export const getLicenseServerKey = async () => {
|
|||||||
}
|
}
|
||||||
export const getLicenseServerUrl = async () => (await client.getSecret("LICENSE_SERVER_URL")).secretValue || "https://portal.infisical.com";
|
export const getLicenseServerUrl = async () => (await client.getSecret("LICENSE_SERVER_URL")).secretValue || "https://portal.infisical.com";
|
||||||
|
|
||||||
// TODO: deprecate from here
|
|
||||||
export const getStripeProductStarter = async () => (await client.getSecret("STRIPE_PRODUCT_STARTER")).secretValue;
|
|
||||||
export const getStripeProductPro = async () => (await client.getSecret("STRIPE_PRODUCT_PRO")).secretValue;
|
|
||||||
export const getStripeProductTeam = async () => (await client.getSecret("STRIPE_PRODUCT_TEAM")).secretValue;
|
|
||||||
export const getStripePublishableKey = async () => (await client.getSecret("STRIPE_PUBLISHABLE_KEY")).secretValue;
|
|
||||||
export const getStripeSecretKey = async () => (await client.getSecret("STRIPE_SECRET_KEY")).secretValue;
|
|
||||||
export const getStripeWebhookSecret = async () => (await client.getSecret("STRIPE_WEBHOOK_SECRET")).secretValue;
|
|
||||||
|
|
||||||
export const getTelemetryEnabled = async () => (await client.getSecret("TELEMETRY_ENABLED")).secretValue !== "false" && true;
|
export const getTelemetryEnabled = async () => (await client.getSecret("TELEMETRY_ENABLED")).secretValue !== "false" && true;
|
||||||
export const getLoopsApiKey = async () => (await client.getSecret("LOOPS_API_KEY")).secretValue;
|
export const getLoopsApiKey = async () => (await client.getSecret("LOOPS_API_KEY")).secretValue;
|
||||||
export const getSmtpConfigured = async () => (await client.getSecret("SMTP_HOST")).secretValue == "" || (await client.getSecret("SMTP_HOST")).secretValue == undefined ? false : true
|
export const getSmtpConfigured = async () => (await client.getSecret("SMTP_HOST")).secretValue == "" || (await client.getSecret("SMTP_HOST")).secretValue == undefined ? false : true
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import * as passwordController from "./passwordController";
|
|||||||
import * as secretController from "./secretController";
|
import * as secretController from "./secretController";
|
||||||
import * as serviceTokenController from "./serviceTokenController";
|
import * as serviceTokenController from "./serviceTokenController";
|
||||||
import * as signupController from "./signupController";
|
import * as signupController from "./signupController";
|
||||||
import * as stripeController from "./stripeController";
|
|
||||||
import * as userActionController from "./userActionController";
|
import * as userActionController from "./userActionController";
|
||||||
import * as userController from "./userController";
|
import * as userController from "./userController";
|
||||||
import * as workspaceController from "./workspaceController";
|
import * as workspaceController from "./workspaceController";
|
||||||
@@ -28,7 +27,6 @@ export {
|
|||||||
secretController,
|
secretController,
|
||||||
serviceTokenController,
|
serviceTokenController,
|
||||||
signupController,
|
signupController,
|
||||||
stripeController,
|
|
||||||
userActionController,
|
userActionController,
|
||||||
userController,
|
userController,
|
||||||
workspaceController,
|
workspaceController,
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { Request, Response } from "express";
|
import { Request, Response } from "express";
|
||||||
import Stripe from "stripe";
|
|
||||||
import {
|
import {
|
||||||
IncidentContactOrg,
|
IncidentContactOrg,
|
||||||
Membership,
|
Membership,
|
||||||
@@ -10,7 +9,8 @@ import {
|
|||||||
import { createOrganization as create } from "../../helpers/organization";
|
import { createOrganization as create } from "../../helpers/organization";
|
||||||
import { addMembershipsOrg } from "../../helpers/membershipOrg";
|
import { addMembershipsOrg } from "../../helpers/membershipOrg";
|
||||||
import { ACCEPTED, OWNER } from "../../variables";
|
import { ACCEPTED, OWNER } from "../../variables";
|
||||||
import { getSiteURL, getStripeSecretKey } from "../../config";
|
import { getSiteURL, getLicenseServerUrl } from "../../config";
|
||||||
|
import { licenseServerKeyRequest } from "../../config/request";
|
||||||
|
|
||||||
export const getOrganizations = async (req: Request, res: Response) => {
|
export const getOrganizations = async (req: Request, res: Response) => {
|
||||||
const organizations = (
|
const organizations = (
|
||||||
@@ -222,7 +222,7 @@ export const deleteOrganizationIncidentContact = async (
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Redirect user to (stripe) billing portal or add card page depending on
|
* Redirect user to billing portal or add card page depending on
|
||||||
* if there is a card on file
|
* if there is a card on file
|
||||||
* @param req
|
* @param req
|
||||||
* @param res
|
* @param res
|
||||||
@@ -232,34 +232,32 @@ export const createOrganizationPortalSession = async (
|
|||||||
req: Request,
|
req: Request,
|
||||||
res: Response
|
res: Response
|
||||||
) => {
|
) => {
|
||||||
let session;
|
const { data: { pmtMethods } } = await licenseServerKeyRequest.get(
|
||||||
const stripe = new Stripe(await getStripeSecretKey(), {
|
`${await getLicenseServerUrl()}/api/license-server/v1/customers/${req.organization.customerId}/billing-details/payment-methods`,
|
||||||
apiVersion: "2022-08-01",
|
);
|
||||||
});
|
|
||||||
|
|
||||||
// check if there is a payment method on file
|
|
||||||
const paymentMethods = await stripe.paymentMethods.list({
|
|
||||||
customer: req.organization.customerId,
|
|
||||||
type: "card",
|
|
||||||
});
|
|
||||||
|
|
||||||
if (paymentMethods.data.length < 1) {
|
if (pmtMethods.length < 1) {
|
||||||
// case: no payment method on file
|
// case: organization has no payment method on file
|
||||||
session = await stripe.checkout.sessions.create({
|
// -> redirect to add payment method portal
|
||||||
customer: req.organization.customerId,
|
const { data: { url } } = await licenseServerKeyRequest.post(
|
||||||
mode: "setup",
|
`${await getLicenseServerUrl()}/api/license-server/v1/customers/${req.organization.customerId}/billing-details/payment-methods`,
|
||||||
payment_method_types: ["card"],
|
{
|
||||||
success_url: (await getSiteURL()) + "/dashboard",
|
success_url: (await getSiteURL()) + "/dashboard",
|
||||||
cancel_url: (await getSiteURL()) + "/dashboard",
|
cancel_url: (await getSiteURL()) + "/dashboard"
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
return res.status(200).send({ url });
|
||||||
} else {
|
} else {
|
||||||
session = await stripe.billingPortal.sessions.create({
|
// case: organization has payment method on file
|
||||||
customer: req.organization.customerId,
|
// -> redirect to billing portal
|
||||||
return_url: (await getSiteURL()) + "/dashboard",
|
const { data: { url } } = await licenseServerKeyRequest.post(
|
||||||
});
|
`${await getLicenseServerUrl()}/api/license-server/v1/customers/${req.organization.customerId}/billing-details/billing-portal`,
|
||||||
|
{
|
||||||
|
return_url: (await getSiteURL()) + "/dashboard"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return res.status(200).send({ url });
|
||||||
}
|
}
|
||||||
|
|
||||||
return res.status(200).send({ url: session.url });
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -272,16 +270,8 @@ export const getOrganizationSubscriptions = async (
|
|||||||
req: Request,
|
req: Request,
|
||||||
res: Response
|
res: Response
|
||||||
) => {
|
) => {
|
||||||
const stripe = new Stripe(await getStripeSecretKey(), {
|
|
||||||
apiVersion: "2022-08-01",
|
|
||||||
});
|
|
||||||
|
|
||||||
const subscriptions = await stripe.subscriptions.list({
|
|
||||||
customer: req.organization.customerId,
|
|
||||||
});
|
|
||||||
|
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
subscriptions,
|
subscriptions: []
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
import { Request, Response } from "express";
|
|
||||||
import Stripe from "stripe";
|
|
||||||
import { getStripeSecretKey, getStripeWebhookSecret } from "../../config";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle service provisioning/un-provisioning via Stripe
|
|
||||||
* @param req
|
|
||||||
* @param res
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
export const handleWebhook = async (req: Request, res: Response) => {
|
|
||||||
// check request for valid stripe signature
|
|
||||||
const stripe = new Stripe(await getStripeSecretKey(), {
|
|
||||||
apiVersion: "2022-08-01",
|
|
||||||
});
|
|
||||||
|
|
||||||
const sig = req.headers["stripe-signature"] as string;
|
|
||||||
const event = stripe.webhooks.constructEvent(
|
|
||||||
req.body,
|
|
||||||
sig,
|
|
||||||
await getStripeWebhookSecret()
|
|
||||||
);
|
|
||||||
|
|
||||||
switch (event.type) {
|
|
||||||
case "":
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
|
|
||||||
return res.json({ received: true });
|
|
||||||
};
|
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
import * as stripeController from "./stripeController";
|
|
||||||
import * as secretController from "./secretController";
|
import * as secretController from "./secretController";
|
||||||
import * as secretSnapshotController from "./secretSnapshotController";
|
import * as secretSnapshotController from "./secretSnapshotController";
|
||||||
import * as organizationsController from "./organizationsController";
|
import * as organizationsController from "./organizationsController";
|
||||||
@@ -8,7 +7,6 @@ import * as membershipController from "./membershipController";
|
|||||||
import * as cloudProductsController from "./cloudProductsController";
|
import * as cloudProductsController from "./cloudProductsController";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
stripeController,
|
|
||||||
secretController,
|
secretController,
|
||||||
secretSnapshotController,
|
secretSnapshotController,
|
||||||
organizationsController,
|
organizationsController,
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ export const getOrganizationPmtMethods = async (req: Request, res: Response) =>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a Stripe session URL to add payment method for organization
|
* Return URL to add payment method for organization
|
||||||
*/
|
*/
|
||||||
export const addOrganizationPmtMethod = async (req: Request, res: Response) => {
|
export const addOrganizationPmtMethod = async (req: Request, res: Response) => {
|
||||||
const {
|
const {
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
import { Request, Response } from "express";
|
|
||||||
import Stripe from "stripe";
|
|
||||||
import { getStripeSecretKey, getStripeWebhookSecret } from "../../../config";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle service provisioning/un-provisioning via Stripe
|
|
||||||
* @param req
|
|
||||||
* @param res
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
export const handleWebhook = async (req: Request, res: Response) => {
|
|
||||||
const stripe = new Stripe(await getStripeSecretKey(), {
|
|
||||||
apiVersion: "2022-08-01",
|
|
||||||
});
|
|
||||||
|
|
||||||
// check request for valid stripe signature
|
|
||||||
const sig = req.headers["stripe-signature"] as string;
|
|
||||||
const event = stripe.webhooks.constructEvent(
|
|
||||||
req.body,
|
|
||||||
sig,
|
|
||||||
await getStripeWebhookSecret()
|
|
||||||
);
|
|
||||||
|
|
||||||
switch (event.type) {
|
|
||||||
case "":
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
|
|
||||||
return res.json({ received: true });
|
|
||||||
};
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
import express from "express";
|
|
||||||
const router = express.Router();
|
|
||||||
import { stripeController } from "../../controllers/v1";
|
|
||||||
|
|
||||||
router.post("/webhook", stripeController.handleWebhook);
|
|
||||||
|
|
||||||
export default router;
|
|
||||||
@@ -83,7 +83,7 @@ class EELicenseService {
|
|||||||
if (!organization) throw OrganizationNotFoundError();
|
if (!organization) throw OrganizationNotFoundError();
|
||||||
|
|
||||||
let url = `${await getLicenseServerUrl()}/api/license-server/v1/customers/${organization.customerId}/cloud-plan`;
|
let url = `${await getLicenseServerUrl()}/api/license-server/v1/customers/${organization.customerId}/cloud-plan`;
|
||||||
|
|
||||||
if (workspaceId) {
|
if (workspaceId) {
|
||||||
url += `?workspaceId=${workspaceId}`;
|
url += `?workspaceId=${workspaceId}`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,13 @@
|
|||||||
import Stripe from "stripe";
|
|
||||||
import { Types } from "mongoose";
|
import { Types } from "mongoose";
|
||||||
import { MembershipOrg, Organization } from "../models";
|
import { MembershipOrg, Organization } from "../models";
|
||||||
import {
|
import {
|
||||||
ACCEPTED,
|
ACCEPTED,
|
||||||
} from "../variables";
|
} from "../variables";
|
||||||
import {
|
|
||||||
getStripeProductPro,
|
|
||||||
getStripeProductStarter,
|
|
||||||
getStripeProductTeam,
|
|
||||||
getStripeSecretKey,
|
|
||||||
} from "../config";
|
|
||||||
import {
|
import {
|
||||||
EELicenseService,
|
EELicenseService,
|
||||||
} from "../ee/services";
|
} from "../ee/services";
|
||||||
import {
|
import {
|
||||||
|
getLicenseServerKey,
|
||||||
getLicenseServerUrl,
|
getLicenseServerUrl,
|
||||||
} from "../config";
|
} from "../config";
|
||||||
import {
|
import {
|
||||||
@@ -35,21 +29,21 @@ export const createOrganization = async ({
|
|||||||
name: string;
|
name: string;
|
||||||
email: string;
|
email: string;
|
||||||
}) => {
|
}) => {
|
||||||
|
const licenseServerKey = await getLicenseServerKey();
|
||||||
let organization;
|
let organization;
|
||||||
// register stripe account
|
|
||||||
const stripe = new Stripe(await getStripeSecretKey(), {
|
if (licenseServerKey) {
|
||||||
apiVersion: "2022-08-01",
|
const { data: { customerId } } = await licenseServerKeyRequest.post(
|
||||||
});
|
`${await getLicenseServerUrl()}/api/license-server/v1/customers`,
|
||||||
|
{
|
||||||
if (await getStripeSecretKey()) {
|
email,
|
||||||
const customer = await stripe.customers.create({
|
name
|
||||||
email,
|
}
|
||||||
description: name,
|
);
|
||||||
});
|
|
||||||
|
|
||||||
organization = await new Organization({
|
organization = await new Organization({
|
||||||
name,
|
name,
|
||||||
customerId: customer.id,
|
customerId
|
||||||
}).save();
|
}).save();
|
||||||
} else {
|
} else {
|
||||||
organization = await new Organization({
|
organization = await new Organization({
|
||||||
@@ -57,68 +51,9 @@ export const createOrganization = async ({
|
|||||||
}).save();
|
}).save();
|
||||||
}
|
}
|
||||||
|
|
||||||
await initSubscriptionOrg({ organizationId: organization._id });
|
|
||||||
|
|
||||||
return organization;
|
return organization;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize free-tier subscription for new organization
|
|
||||||
* @param {Object} obj
|
|
||||||
* @param {String} obj.organizationId - id of associated organization for subscription
|
|
||||||
* @return {Object} obj
|
|
||||||
* @return {Object} obj.stripeSubscription - new stripe subscription
|
|
||||||
* @return {Subscription} obj.subscription - new subscription
|
|
||||||
*/
|
|
||||||
export const initSubscriptionOrg = async ({
|
|
||||||
organizationId,
|
|
||||||
}: {
|
|
||||||
organizationId: Types.ObjectId;
|
|
||||||
}) => {
|
|
||||||
let stripeSubscription;
|
|
||||||
let subscription;
|
|
||||||
|
|
||||||
// find organization
|
|
||||||
const organization = await Organization.findOne({
|
|
||||||
_id: organizationId,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (organization) {
|
|
||||||
if (organization.customerId) {
|
|
||||||
// initialize starter subscription with quantity of 0
|
|
||||||
const stripe = new Stripe(await getStripeSecretKey(), {
|
|
||||||
apiVersion: "2022-08-01",
|
|
||||||
});
|
|
||||||
|
|
||||||
const productToPriceMap = {
|
|
||||||
starter: await getStripeProductStarter(),
|
|
||||||
team: await getStripeProductTeam(),
|
|
||||||
pro: await getStripeProductPro(),
|
|
||||||
};
|
|
||||||
|
|
||||||
stripeSubscription = await stripe.subscriptions.create({
|
|
||||||
customer: organization.customerId,
|
|
||||||
items: [
|
|
||||||
{
|
|
||||||
price: productToPriceMap["starter"],
|
|
||||||
quantity: 1,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
payment_behavior: "default_incomplete",
|
|
||||||
proration_behavior: "none",
|
|
||||||
expand: ["latest_invoice.payment_intent"],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new Error("Failed to initialize free organization subscription");
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
stripeSubscription,
|
|
||||||
subscription,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update organization subscription quantity to reflect number of members in
|
* Update organization subscription quantity to reflect number of members in
|
||||||
* the organization.
|
* the organization.
|
||||||
@@ -130,7 +65,6 @@ export const updateSubscriptionOrgQuantity = async ({
|
|||||||
}: {
|
}: {
|
||||||
organizationId: string;
|
organizationId: string;
|
||||||
}) => {
|
}) => {
|
||||||
let stripeSubscription;
|
|
||||||
// find organization
|
// find organization
|
||||||
const organization = await Organization.findOne({
|
const organization = await Organization.findOne({
|
||||||
_id: organizationId,
|
_id: organizationId,
|
||||||
@@ -171,6 +105,4 @@ export const updateSubscriptionOrgQuantity = async ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
await EELicenseService.refreshPlan(organizationId);
|
await EELicenseService.refreshPlan(organizationId);
|
||||||
|
|
||||||
return stripeSubscription;
|
|
||||||
};
|
};
|
||||||
@@ -37,7 +37,6 @@ import {
|
|||||||
secretsFolder as v1SecretsFolder,
|
secretsFolder as v1SecretsFolder,
|
||||||
serviceToken as v1ServiceTokenRouter,
|
serviceToken as v1ServiceTokenRouter,
|
||||||
signup as v1SignupRouter,
|
signup as v1SignupRouter,
|
||||||
stripe as v1StripeRouter,
|
|
||||||
userAction as v1UserActionRouter,
|
userAction as v1UserActionRouter,
|
||||||
user as v1UserRouter,
|
user as v1UserRouter,
|
||||||
workspace as v1WorkspaceRouter,
|
workspace as v1WorkspaceRouter,
|
||||||
@@ -123,7 +122,6 @@ const main = async () => {
|
|||||||
app.use("/api/v1/secret", v1SecretRouter); // deprecate
|
app.use("/api/v1/secret", v1SecretRouter); // deprecate
|
||||||
app.use("/api/v1/service-token", v1ServiceTokenRouter); // deprecate
|
app.use("/api/v1/service-token", v1ServiceTokenRouter); // deprecate
|
||||||
app.use("/api/v1/password", v1PasswordRouter);
|
app.use("/api/v1/password", v1PasswordRouter);
|
||||||
app.use("/api/v1/stripe", v1StripeRouter);
|
|
||||||
app.use("/api/v1/integration", v1IntegrationRouter);
|
app.use("/api/v1/integration", v1IntegrationRouter);
|
||||||
app.use("/api/v1/integration-auth", v1IntegrationAuthRouter);
|
app.use("/api/v1/integration-auth", v1IntegrationAuthRouter);
|
||||||
app.use("/api/v1/folders", v1SecretsFolder);
|
app.use("/api/v1/folders", v1SecretsFolder);
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import inviteOrg from "./inviteOrg";
|
|||||||
import secret from "./secret";
|
import secret from "./secret";
|
||||||
import serviceToken from "./serviceToken";
|
import serviceToken from "./serviceToken";
|
||||||
import password from "./password";
|
import password from "./password";
|
||||||
import stripe from "./stripe";
|
|
||||||
import integration from "./integration";
|
import integration from "./integration";
|
||||||
import integrationAuth from "./integrationAuth";
|
import integrationAuth from "./integrationAuth";
|
||||||
import secretsFolder from "./secretsFolder";
|
import secretsFolder from "./secretsFolder";
|
||||||
@@ -32,7 +31,6 @@ export {
|
|||||||
secret,
|
secret,
|
||||||
serviceToken,
|
serviceToken,
|
||||||
password,
|
password,
|
||||||
stripe,
|
|
||||||
integration,
|
integration,
|
||||||
integrationAuth,
|
integrationAuth,
|
||||||
secretsFolder,
|
secretsFolder,
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
import express from "express";
|
|
||||||
const router = express.Router();
|
|
||||||
import { stripeController } from "../../controllers/v1";
|
|
||||||
|
|
||||||
router.post("/webhook", stripeController.handleWebhook);
|
|
||||||
|
|
||||||
export default router;
|
|
||||||
@@ -8,6 +8,5 @@ export * from "./organization";
|
|||||||
export * from "./permission";
|
export * from "./permission";
|
||||||
export * from "./secret";
|
export * from "./secret";
|
||||||
export * from "./smtp";
|
export * from "./smtp";
|
||||||
export * from "./stripe";
|
|
||||||
export * from "./token";
|
export * from "./token";
|
||||||
export * from "./user";
|
export * from "./user";
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
export const PLAN_STARTER = "starter";
|
|
||||||
export const PLAN_PRO = "pro";
|
|
||||||
@@ -55,9 +55,6 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
- NEXT_PUBLIC_ENV=development
|
- NEXT_PUBLIC_ENV=development
|
||||||
- INFISICAL_TELEMETRY_ENABLED=${TELEMETRY_ENABLED}
|
- INFISICAL_TELEMETRY_ENABLED=${TELEMETRY_ENABLED}
|
||||||
- NEXT_PUBLIC_STRIPE_PRODUCT_PRO=${STRIPE_PRODUCT_PRO}
|
|
||||||
- NEXT_PUBLIC_STRIPE_PRODUCT_TEAM=${STRIPE_PRODUCT_TEAM}
|
|
||||||
- NEXT_PUBLIC_STRIPE_PRODUCT_STARTER=${STRIPE_PRODUCT_STARTER}
|
|
||||||
networks:
|
networks:
|
||||||
- infisical-dev
|
- infisical-dev
|
||||||
|
|
||||||
|
|||||||
@@ -38,9 +38,6 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
# - NEXT_PUBLIC_POSTHOG_API_KEY=${POSTHOG_PROJECT_API_KEY}
|
# - NEXT_PUBLIC_POSTHOG_API_KEY=${POSTHOG_PROJECT_API_KEY}
|
||||||
- INFISICAL_TELEMETRY_ENABLED=${TELEMETRY_ENABLED}
|
- INFISICAL_TELEMETRY_ENABLED=${TELEMETRY_ENABLED}
|
||||||
- NEXT_PUBLIC_STRIPE_PRODUCT_PRO=${STRIPE_PRODUCT_PRO}
|
|
||||||
- NEXT_PUBLIC_STRIPE_PRODUCT_TEAM=${STRIPE_PRODUCT_TEAM}
|
|
||||||
- NEXT_PUBLIC_STRIPE_PRODUCT_STARTER=${STRIPE_PRODUCT_STARTER}
|
|
||||||
networks:
|
networks:
|
||||||
- infisical
|
- infisical
|
||||||
|
|
||||||
|
|||||||
@@ -2,14 +2,11 @@ const ENV = process.env.NEXT_PUBLIC_ENV! || "development"; // investigate
|
|||||||
const POSTHOG_API_KEY = process.env.NEXT_PUBLIC_POSTHOG_API_KEY!;
|
const POSTHOG_API_KEY = process.env.NEXT_PUBLIC_POSTHOG_API_KEY!;
|
||||||
const POSTHOG_HOST =
|
const POSTHOG_HOST =
|
||||||
process.env.NEXT_PUBLIC_POSTHOG_HOST! || "https://app.posthog.com";
|
process.env.NEXT_PUBLIC_POSTHOG_HOST! || "https://app.posthog.com";
|
||||||
const STRIPE_PRODUCT_PRO = process.env.NEXT_PUBLIC_STRIPE_PRODUCT_PRO!;
|
|
||||||
const STRIPE_PRODUCT_STARTER = process.env.NEXT_PUBLIC_STRIPE_PRODUCT_STARTER!;
|
|
||||||
const INTERCOM_ID = process.env.NEXT_PUBLIC_INTERCOM_ID!;
|
const INTERCOM_ID = process.env.NEXT_PUBLIC_INTERCOM_ID!;
|
||||||
|
|
||||||
export {
|
export {
|
||||||
ENV,
|
ENV,
|
||||||
INTERCOM_ID,
|
INTERCOM_ID,
|
||||||
POSTHOG_API_KEY,
|
POSTHOG_API_KEY,
|
||||||
POSTHOG_HOST,
|
POSTHOG_HOST
|
||||||
STRIPE_PRODUCT_PRO,
|
};
|
||||||
STRIPE_PRODUCT_STARTER};
|
|
||||||
@@ -1,16 +1,12 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
|
|
||||||
import Plan from "@app/components/billing/Plan";
|
import Plan from "@app/components/billing/Plan";
|
||||||
import NavHeader from "@app/components/navigation/NavHeader";
|
import NavHeader from "@app/components/navigation/NavHeader";
|
||||||
import { plans as plansConstant } from "@app/const";
|
import { useSubscription } from "@app/context";
|
||||||
|
|
||||||
import getOrganizationSubscriptions from "../../api/organization/GetOrgSubscription";
|
|
||||||
import getOrganizationUsers from "../../api/organization/GetOrgUsers";
|
|
||||||
|
|
||||||
export default function SettingsBilling() {
|
export default function SettingsBilling() {
|
||||||
const [currentPlan, setCurrentPlan] = useState("");
|
const { subscription } = useSubscription();
|
||||||
const [numUsers, setNumUsers] = useState(0);
|
const [numUsers, setNumUsers] = useState(0);
|
||||||
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@@ -25,7 +21,7 @@ export default function SettingsBilling() {
|
|||||||
subtext: t("billing.starter.subtext")!,
|
subtext: t("billing.starter.subtext")!,
|
||||||
buttonTextMain: t("billing.downgrade")!,
|
buttonTextMain: t("billing.downgrade")!,
|
||||||
buttonTextSecondary: t("billing.learn-more")!,
|
buttonTextSecondary: t("billing.learn-more")!,
|
||||||
current: currentPlan === plansConstant.starter
|
current: subscription?.slug === "starter" // subscription.slug?
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 2,
|
key: 2,
|
||||||
@@ -35,7 +31,7 @@ export default function SettingsBilling() {
|
|||||||
text: "Unlimited members, up to 10 projects. Additional developer experience features.",
|
text: "Unlimited members, up to 10 projects. Additional developer experience features.",
|
||||||
buttonTextMain: t("billing.upgrade")!,
|
buttonTextMain: t("billing.upgrade")!,
|
||||||
buttonTextSecondary: t("billing.learn-more")!,
|
buttonTextSecondary: t("billing.learn-more")!,
|
||||||
current: currentPlan === plansConstant.team
|
current: subscription?.slug === "team" || subscription?.slug === "team-annual"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 3,
|
key: 3,
|
||||||
@@ -46,7 +42,7 @@ export default function SettingsBilling() {
|
|||||||
subtext: t("billing.professional.subtext")!,
|
subtext: t("billing.professional.subtext")!,
|
||||||
buttonTextMain: t("billing.upgrade")!,
|
buttonTextMain: t("billing.upgrade")!,
|
||||||
buttonTextSecondary: t("billing.learn-more")!,
|
buttonTextSecondary: t("billing.learn-more")!,
|
||||||
current: currentPlan === plansConstant.professional
|
current: subscription?.slug === "pro" || subscription?.slug === "pro-annual"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 4,
|
key: 4,
|
||||||
@@ -55,26 +51,10 @@ export default function SettingsBilling() {
|
|||||||
text: "Boost the security and efficiency of your engineering teams.",
|
text: "Boost the security and efficiency of your engineering teams.",
|
||||||
buttonTextMain: t("billing.schedule-demo")!,
|
buttonTextMain: t("billing.schedule-demo")!,
|
||||||
buttonTextSecondary: t("billing.learn-more")!,
|
buttonTextSecondary: t("billing.learn-more")!,
|
||||||
current: false
|
current: subscription?.slug === "enterprise"
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
(async () => {
|
|
||||||
const orgId = localStorage.getItem("orgData.id") as string;
|
|
||||||
const subscriptions = await getOrganizationSubscriptions({
|
|
||||||
orgId
|
|
||||||
});
|
|
||||||
if (subscriptions) {
|
|
||||||
setCurrentPlan(subscriptions.data[0].plan.product);
|
|
||||||
}
|
|
||||||
const orgUsers = await getOrganizationUsers({
|
|
||||||
orgId
|
|
||||||
});
|
|
||||||
setNumUsers(orgUsers.length);
|
|
||||||
})();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col justify-between bg-bunker-800 pb-4 text-white">
|
<div className="flex flex-col justify-between bg-bunker-800 pb-4 text-white">
|
||||||
<Head>
|
<Head>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { plans } from "public/data/frequentConstants";
|
|
||||||
|
|
||||||
import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider";
|
import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider";
|
||||||
import NavHeader from "@app/components/navigation/NavHeader";
|
import NavHeader from "@app/components/navigation/NavHeader";
|
||||||
|
|||||||
Reference in New Issue
Block a user