diff --git a/packages/server/src/enterprise/controllers/organization.controller.ts b/packages/server/src/enterprise/controllers/organization.controller.ts index b7ca0a6d7..f2af58fd8 100644 --- a/packages/server/src/enterprise/controllers/organization.controller.ts +++ b/packages/server/src/enterprise/controllers/organization.controller.ts @@ -7,6 +7,7 @@ import { Organization } from '../database/entities/organization.entity' import { GeneralErrorMessage } from '../../utils/constants' import { OrganizationUserService } from '../services/organization-user.service' import { getCurrentUsage } from '../../utils/quotaUsage' +import { assertStripeIdMatchesSession } from '../utils/tenantRequestGuards' export class OrganizationController { public async create(req: Request, res: Response, next: NextFunction) { @@ -62,6 +63,7 @@ export class OrganizationController { if (!subscriptionId) { return res.status(400).json({ error: 'Subscription ID is required' }) } + assertStripeIdMatchesSession(subscriptionId as string, req.user?.activeOrganizationSubscriptionId) const organizationUserservice = new OrganizationUserService() const totalOrgUsers = await organizationUserservice.readOrgUsersCountByOrgId(req.user?.activeOrganizationId as string) @@ -80,6 +82,7 @@ export class OrganizationController { if (!customerId) { return res.status(400).json({ error: 'Customer ID is required' }) } + assertStripeIdMatchesSession(customerId as string, req.user?.activeOrganizationCustomerId) const identityManager = getRunningExpressApp().identityManager const result = await identityManager.getCustomerWithDefaultSource(customerId as string) @@ -93,11 +96,12 @@ export class OrganizationController { try { const { subscriptionId, quantity } = req.query if (!subscriptionId) { - return res.status(400).json({ error: 'Customer ID is required' }) + return res.status(400).json({ error: 'Subscription ID is required' }) } if (quantity === undefined) { return res.status(400).json({ error: 'Quantity is required' }) } + assertStripeIdMatchesSession(subscriptionId as string, req.user?.activeOrganizationSubscriptionId) const identityManager = getRunningExpressApp().identityManager const result = await identityManager.getAdditionalSeatsProration(subscriptionId as string, parseInt(quantity as string)) @@ -116,6 +120,7 @@ export class OrganizationController { if (!newPlanId) { return res.status(400).json({ error: 'New plan ID is required' }) } + assertStripeIdMatchesSession(subscriptionId as string, req.user?.activeOrganizationSubscriptionId) const identityManager = getRunningExpressApp().identityManager const result = await identityManager.getPlanProration(subscriptionId as string, newPlanId as string) @@ -137,6 +142,7 @@ export class OrganizationController { if (!prorationDate) { return res.status(400).json({ error: 'Proration date is required' }) } + assertStripeIdMatchesSession(subscriptionId, req.user?.activeOrganizationSubscriptionId) const identityManager = getRunningExpressApp().identityManager const result = await identityManager.updateAdditionalSeats(subscriptionId, quantity, prorationDate) @@ -158,6 +164,7 @@ export class OrganizationController { if (!prorationDate) { return res.status(400).json({ error: 'Proration date is required' }) } + assertStripeIdMatchesSession(subscriptionId, req.user?.activeOrganizationSubscriptionId) const identityManager = getRunningExpressApp().identityManager const result = await identityManager.updateSubscriptionPlan(req, subscriptionId, newPlanId, prorationDate) diff --git a/packages/server/src/enterprise/utils/tenantRequestGuards.ts b/packages/server/src/enterprise/utils/tenantRequestGuards.ts index 54ad720df..e76132678 100644 --- a/packages/server/src/enterprise/utils/tenantRequestGuards.ts +++ b/packages/server/src/enterprise/utils/tenantRequestGuards.ts @@ -65,6 +65,12 @@ export async function assertWorkspaceIdAccessibleToUser( throw new InternalFlowiseError(StatusCodes.FORBIDDEN, GeneralErrorMessage.FORBIDDEN) } +export function assertStripeIdMatchesSession(requestedId: string, activeId: string | undefined): void { + if (!activeId || requestedId !== activeId) { + throw new InternalFlowiseError(StatusCodes.FORBIDDEN, GeneralErrorMessage.FORBIDDEN) + } +} + export function userMayManageOrgUsers(user: LoggedInUser): boolean { return user.isOrganizationAdmin === true || (user.permissions?.includes('users:manage') ?? false) }