Finish removing Stripe from codebase

This commit is contained in:
Tuan Dang
2023-06-22 16:38:02 +07:00
parent f3e84dc6eb
commit 28943f3b6f
25 changed files with 52 additions and 290 deletions

View File

@@ -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
View File

@@ -2,6 +2,7 @@
node_modules node_modules
.env .env
.env.dev .env.dev
.env.gamma
.env.prod .env.prod
.env.infisical .env.infisical

View File

@@ -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;
} }

View File

@@ -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",

View File

@@ -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",

View File

@@ -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

View File

@@ -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,

View File

@@ -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: []
}); });
}; };

View File

@@ -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 });
};

View File

@@ -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,

View File

@@ -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 {

View File

@@ -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 });
};

View File

@@ -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;

View File

@@ -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}`;
} }

View File

@@ -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;
}; };

View File

@@ -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);

View File

@@ -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,

View File

@@ -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;

View File

@@ -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";

View File

@@ -1,2 +0,0 @@
export const PLAN_STARTER = "starter";
export const PLAN_PRO = "pro";

View File

@@ -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

View File

@@ -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

View File

@@ -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};

View File

@@ -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>

View File

@@ -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";