diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index cd598007613..b3b2abc2e8c 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -26,7 +26,7 @@ import { RedisEventSubscriber } from './queue/RedisEventSubscriber' import flowiseApiV1Router from './routes' import { UsageCacheManager } from './UsageCacheManager' import { getEncryptionKey, getNodeModulesPackagePath } from './utils' -import { WHITELIST_URLS } from './utils/constants' +import { API_KEY_BLACKLIST_URLS, WHITELIST_URLS } from './utils/constants' import logger, { expressRequestLogger } from './utils/logger' import { RateLimiterManager } from './utils/rateLimit' import { SSEStreamer } from './utils/SSEStreamer' @@ -224,6 +224,11 @@ export class App { } else if (req.headers['x-request-from'] === 'internal') { verifyToken(req, res, next) } else { + const isAPIKeyBlacklistedURLS = API_KEY_BLACKLIST_URLS.some((url) => req.path.startsWith(url)) + if (isAPIKeyBlacklistedURLS) { + return res.status(401).json({ error: 'Unauthorized Access' }) + } + // Only check license validity for non-open-source platforms if (this.identityManager.getPlatformType() !== Platform.OPEN_SOURCE) { if (!this.identityManager.isLicenseValid()) { diff --git a/packages/server/src/utils/constants.ts b/packages/server/src/utils/constants.ts index 7b94bcabe23..cc10007ef42 100644 --- a/packages/server/src/utils/constants.ts +++ b/packages/server/src/utils/constants.ts @@ -10,7 +10,6 @@ export const WHITELIST_URLS = [ '/api/v1/public-chatbotConfig', '/api/v1/public-executions', '/api/v1/prediction/', - '/api/v1/vector/upsert/', '/api/v1/node-icon/', '/api/v1/components-credentials-icon/', '/api/v1/chatflows-streaming', @@ -23,7 +22,6 @@ export const WHITELIST_URLS = [ '/api/v1/ping', '/api/v1/version', '/api/v1/attachments', - '/api/v1/nvidia-nim', '/api/v1/auth/resolve', '/api/v1/auth/login', '/api/v1/auth/refreshToken', @@ -56,6 +54,8 @@ export const WHITELIST_URLS = [ GithubSSO.CALLBACK_URI ] +export const API_KEY_BLACKLIST_URLS = ['/api/v1/nvidia-nim'] + export const enum GeneralErrorMessage { UNAUTHORIZED = 'Unauthorized', UNHANDLED_EDGE_CASE = 'Unhandled Edge Case', diff --git a/packages/server/src/utils/upsertVector.ts b/packages/server/src/utils/upsertVector.ts index b89e82928e0..b7c17b45dcf 100644 --- a/packages/server/src/utils/upsertVector.ts +++ b/packages/server/src/utils/upsertVector.ts @@ -1,43 +1,43 @@ import { Request } from 'express' -import * as path from 'path' -import { cloneDeep, omit } from 'lodash' import { - IMessage, addArrayFilesToStorage, - mapMimeTypeToInputField, - mapExtToInputField, getFileFromUpload, + IMessage, + mapExtToInputField, + mapMimeTypeToInputField, removeSpecificFileFromUpload } from 'flowise-components' -import logger from '../utils/logger' +import { StatusCodes } from 'http-status-codes' +import { cloneDeep, omit } from 'lodash' +import * as path from 'path' +import { v4 as uuidv4 } from 'uuid' +import { ChatType, IExecuteFlowParams, IncomingInput, INodeDirectedGraph, IReactFlowObject, MODE } from '../Interface' +import { FLOWISE_COUNTER_STATUS, FLOWISE_METRIC_COUNTERS } from '../Interface.Metrics' +import { ChatFlow } from '../database/entities/ChatFlow' +import { UpsertHistory } from '../database/entities/UpsertHistory' +import { Variable } from '../database/entities/Variable' +import { Organization } from '../enterprise/database/entities/organization.entity' +import { Workspace } from '../enterprise/database/entities/workspace.entity' +import { getWorkspaceSearchOptions } from '../enterprise/utils/ControllerServiceUtils' +import { InternalFlowiseError } from '../errors/internalFlowiseError' +import { getErrorMessage } from '../errors/utils' import { buildFlow, constructGraphs, - getAllConnectedNodes, findMemoryNode, - getMemorySessionId, + getAllConnectedNodes, + getAPIOverrideConfig, getAppVersion, - getTelemetryFlowObj, + getMemorySessionId, getStartingNodes, - getAPIOverrideConfig + getTelemetryFlowObj } from '../utils' -import { validateFlowAPIKey } from './validateKey' -import { IncomingInput, INodeDirectedGraph, IReactFlowObject, ChatType, IExecuteFlowParams, MODE } from '../Interface' -import { ChatFlow } from '../database/entities/ChatFlow' import { getRunningExpressApp } from '../utils/getRunningExpressApp' -import { UpsertHistory } from '../database/entities/UpsertHistory' -import { InternalFlowiseError } from '../errors/internalFlowiseError' -import { StatusCodes } from 'http-status-codes' -import { checkStorage, updateStorageUsage } from './quotaUsage' -import { validateFileMimeTypeAndExtensionMatch } from './fileValidation' -import { getErrorMessage } from '../errors/utils' -import { v4 as uuidv4 } from 'uuid' -import { FLOWISE_COUNTER_STATUS, FLOWISE_METRIC_COUNTERS } from '../Interface.Metrics' -import { Variable } from '../database/entities/Variable' -import { getWorkspaceSearchOptions } from '../enterprise/utils/ControllerServiceUtils' +import logger from '../utils/logger' import { OMIT_QUEUE_JOB_DATA } from './constants' -import { Workspace } from '../enterprise/database/entities/workspace.entity' -import { Organization } from '../enterprise/database/entities/organization.entity' +import { validateFileMimeTypeAndExtensionMatch } from './fileValidation' +import { checkStorage, updateStorageUsage } from './quotaUsage' +import { validateFlowAPIKey } from './validateKey' export const executeUpsert = async ({ componentNodes, @@ -262,7 +262,6 @@ export const upsertVector = async (req: Request, isInternal: boolean = false) => } } - // This can be public API, so we can only get orgId from the chatflow const chatflowWorkspaceId = chatflow.workspaceId const workspace = await appServer.AppDataSource.getRepository(Workspace).findOneBy({ id: chatflowWorkspaceId @@ -272,6 +271,8 @@ export const upsertVector = async (req: Request, isInternal: boolean = false) => } const workspaceId = workspace.id + if (workspaceId !== req.user?.activeWorkspaceId) throw new InternalFlowiseError(StatusCodes.UNAUTHORIZED, 'Unauthorized') + const org = await appServer.AppDataSource.getRepository(Organization).findOneBy({ id: workspace.organizationId })