From 156ab31fbd2ab3eb1b544905ccbc04be5ab3e194 Mon Sep 17 00:00:00 2001 From: Vinod Paidimarry Date: Sun, 20 Jul 2025 17:02:26 +0530 Subject: [PATCH 1/7] feat: Require workspace ID for API key operations - Added validation to ensure `activeWorkspaceId` is present in user requests for all API key operations (get, create, update, import, delete). - Updated `getWorkspaceSearchOptions` and `getWorkspaceSearchOptionsFromReq` to throw an error if `workspaceId` is not provided. - Modified service methods to enforce `workspaceId` as a required parameter for database operations related to API keys. --- packages/server/src/controllers/apikey/index.ts | 15 +++++++++++++++ .../enterprise/utils/ControllerServiceUtils.ts | 12 ++++++++++-- packages/server/src/services/apikey/index.ts | 15 ++++++++------- 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/packages/server/src/controllers/apikey/index.ts b/packages/server/src/controllers/apikey/index.ts index 340ff27b251..a13f02f7f20 100644 --- a/packages/server/src/controllers/apikey/index.ts +++ b/packages/server/src/controllers/apikey/index.ts @@ -9,6 +9,9 @@ const getAllApiKeys = async (req: Request, res: Response, next: NextFunction) => try { const autoCreateNewKey = true const { page, limit } = getPageAndLimitParams(req) + if (!req.user?.activeWorkspaceId) { + throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Workspace ID is required`) + } const apiResponse = await apikeyService.getAllApiKeys(req.user?.activeWorkspaceId, autoCreateNewKey, page, limit) return res.json(apiResponse) } catch (error) { @@ -21,6 +24,9 @@ const createApiKey = async (req: Request, res: Response, next: NextFunction) => if (typeof req.body === 'undefined' || !req.body.keyName) { throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Error: apikeyController.createApiKey - keyName not provided!`) } + if (!req.user?.activeWorkspaceId) { + throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Workspace ID is required`) + } const apiResponse = await apikeyService.createApiKey(req.body.keyName, req.user?.activeWorkspaceId) return res.json(apiResponse) } catch (error) { @@ -36,6 +42,9 @@ const updateApiKey = async (req: Request, res: Response, next: NextFunction) => } if (typeof req.body === 'undefined' || !req.body.keyName) { throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Error: apikeyController.updateApiKey - keyName not provided!`) + } + if (!req.user?.activeWorkspaceId) { + throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Workspace ID is required`) } const apiResponse = await apikeyService.updateApiKey(req.params.id, req.body.keyName, req.user?.activeWorkspaceId) return res.json(apiResponse) @@ -50,6 +59,9 @@ const importKeys = async (req: Request, res: Response, next: NextFunction) => { if (typeof req.body === 'undefined' || !req.body.jsonFile) { throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Error: apikeyController.importKeys - body not provided!`) } + if (!req.user?.activeWorkspaceId) { + throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Workspace ID is required`) + } req.body.workspaceId = req.user?.activeWorkspaceId const apiResponse = await apikeyService.importKeys(req.body) return res.json(apiResponse) @@ -64,6 +76,9 @@ const deleteApiKey = async (req: Request, res: Response, next: NextFunction) => if (typeof req.params === 'undefined' || !req.params.id) { throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Error: apikeyController.deleteApiKey - id not provided!`) } + if (!req.user?.activeWorkspaceId) { + throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Workspace ID is required`) + } const apiResponse = await apikeyService.deleteApiKey(req.params.id, req.user?.activeWorkspaceId) return res.json(apiResponse) } catch (error) { diff --git a/packages/server/src/enterprise/utils/ControllerServiceUtils.ts b/packages/server/src/enterprise/utils/ControllerServiceUtils.ts index 245f1e4711e..1d0983c6761 100644 --- a/packages/server/src/enterprise/utils/ControllerServiceUtils.ts +++ b/packages/server/src/enterprise/utils/ControllerServiceUtils.ts @@ -1,11 +1,19 @@ import { Equal } from 'typeorm' import { Request } from 'express' +import { InternalFlowiseError } from '../../errors/internalFlowiseError' +import { StatusCodes } from 'http-status-codes' export const getWorkspaceSearchOptions = (workspaceId?: string) => { - return workspaceId ? { workspaceId: Equal(workspaceId) } : {} + if (!workspaceId) { + throw new InternalFlowiseError(StatusCodes.BAD_REQUEST, `Workspace ID is required`) + } + return { workspaceId: Equal(workspaceId) } } export const getWorkspaceSearchOptionsFromReq = (req: Request) => { const workspaceId = req.user?.activeWorkspaceId - return workspaceId ? { workspaceId: Equal(workspaceId) } : {} + if (!workspaceId) { + throw new InternalFlowiseError(StatusCodes.BAD_REQUEST, `Workspace ID is required`) + } + return { workspaceId: Equal(workspaceId) } } diff --git a/packages/server/src/services/apikey/index.ts b/packages/server/src/services/apikey/index.ts index a8b6036333a..5e009c92774 100644 --- a/packages/server/src/services/apikey/index.ts +++ b/packages/server/src/services/apikey/index.ts @@ -9,14 +9,14 @@ import { Not, IsNull } from 'typeorm' import { getWorkspaceSearchOptions } from '../../enterprise/utils/ControllerServiceUtils' import { v4 as uuidv4 } from 'uuid' -const getAllApiKeysFromDB = async (workspaceId?: string, page: number = -1, limit: number = -1) => { +const getAllApiKeysFromDB = async (workspaceId: string, page: number = -1, limit: number = -1) => { const appServer = getRunningExpressApp() const queryBuilder = appServer.AppDataSource.getRepository(ApiKey).createQueryBuilder('api_key').orderBy('api_key.updatedDate', 'DESC') if (page > 0 && limit > 0) { queryBuilder.skip((page - 1) * limit) queryBuilder.take(limit) } - if (workspaceId) queryBuilder.andWhere('api_key.workspaceId = :workspaceId', { workspaceId }) + queryBuilder.andWhere('api_key.workspaceId = :workspaceId', { workspaceId }) const [data, total] = await queryBuilder.getManyAndCount() const keysWithChatflows = await addChatflowsCount(data) @@ -27,7 +27,7 @@ const getAllApiKeysFromDB = async (workspaceId?: string, page: number = -1, limi } } -const getAllApiKeys = async (workspaceId?: string, autoCreateNewKey?: boolean, page: number = -1, limit: number = -1) => { +const getAllApiKeys = async (workspaceId: string, autoCreateNewKey?: boolean, page: number = -1, limit: number = -1) => { try { let keys = await getAllApiKeysFromDB(workspaceId, page, limit) const isEmpty = keys?.total === 0 || (Array.isArray(keys) && keys?.length === 0) @@ -71,7 +71,7 @@ const getApiKeyById = async (apiKeyId: string) => { } } -const createApiKey = async (keyName: string, workspaceId?: string) => { +const createApiKey = async (keyName: string, workspaceId: string) => { try { const apiKey = generateAPIKey() const apiSecret = generateSecretHash(apiKey) @@ -91,11 +91,12 @@ const createApiKey = async (keyName: string, workspaceId?: string) => { } // Update api key -const updateApiKey = async (id: string, keyName: string, workspaceId?: string) => { +const updateApiKey = async (id: string, keyName: string, workspaceId: string) => { try { const appServer = getRunningExpressApp() const currentKey = await appServer.AppDataSource.getRepository(ApiKey).findOneBy({ - id: id + id: id, + workspaceId: workspaceId }) if (!currentKey) { throw new InternalFlowiseError(StatusCodes.NOT_FOUND, `ApiKey ${currentKey} not found`) @@ -108,7 +109,7 @@ const updateApiKey = async (id: string, keyName: string, workspaceId?: string) = } } -const deleteApiKey = async (id: string, workspaceId?: string) => { +const deleteApiKey = async (id: string, workspaceId: string) => { try { const appServer = getRunningExpressApp() const dbResponse = await appServer.AppDataSource.getRepository(ApiKey).delete({ id, workspaceId }) From 0d1c238807031e8b49075c2450c3248f94005461 Mon Sep 17 00:00:00 2001 From: Vinod Kiran Date: Wed, 30 Jul 2025 10:27:41 +0530 Subject: [PATCH 2/7] feat: Enforce workspace ID as a required field across multiple interfaces and services - Updated various interfaces to make `workspaceId` a mandatory field instead of optional. - Enhanced assistant and export-import service methods to require `workspaceId` for operations, ensuring proper validation and error handling. - Modified database entity definitions to reflect the change in `workspaceId` from optional to required. - Improved error handling in controllers to check for `activeWorkspaceId` before proceeding with requests. --- packages/server/src/Interface.ts | 18 ++++---- .../src/controllers/assistants/index.ts | 45 ++++++++++++++++--- .../src/controllers/export-import/index.ts | 12 +++-- .../server/src/database/entities/ApiKey.ts | 4 +- .../server/src/database/entities/Assistant.ts | 4 +- .../server/src/database/entities/ChatFlow.ts | 4 +- .../src/database/entities/Credential.ts | 4 +- .../src/database/entities/CustomTemplate.ts | 2 +- .../server/src/database/entities/Dataset.ts | 4 +- .../src/database/entities/DocumentStore.ts | 4 +- .../src/database/entities/Evaluation.ts | 4 +- .../server/src/database/entities/Evaluator.ts | 4 +- .../server/src/database/entities/Execution.ts | 4 +- packages/server/src/database/entities/Tool.ts | 4 +- .../server/src/database/entities/Variable.ts | 4 +- .../server/src/services/assistants/index.ts | 21 +++++---- .../src/services/export-import/index.ts | 8 ++-- packages/server/src/utils/index.ts | 3 +- 18 files changed, 98 insertions(+), 55 deletions(-) diff --git a/packages/server/src/Interface.ts b/packages/server/src/Interface.ts index 97f66d10920..3e72217c46a 100644 --- a/packages/server/src/Interface.ts +++ b/packages/server/src/Interface.ts @@ -69,7 +69,7 @@ export interface IChatFlow { apiConfig?: string category?: string type?: ChatflowType - workspaceId?: string + workspaceId: string } export interface IChatMessage { @@ -114,7 +114,7 @@ export interface ITool { func?: string updatedDate: Date createdDate: Date - workspaceId?: string + workspaceId: string } export interface IAssistant { @@ -124,7 +124,7 @@ export interface IAssistant { iconSrc?: string updatedDate: Date createdDate: Date - workspaceId?: string + workspaceId: string } export interface ICredential { @@ -134,7 +134,7 @@ export interface ICredential { encryptedData: string updatedDate: Date createdDate: Date - workspaceId?: string + workspaceId: string } export interface IVariable { @@ -144,7 +144,7 @@ export interface IVariable { type: string updatedDate: Date createdDate: Date - workspaceId?: string + workspaceId: string } export interface ILead { @@ -176,7 +176,7 @@ export interface IExecution { createdDate: Date updatedDate: Date stoppedDate: Date - workspaceId?: string + workspaceId: string } export interface IComponentNodes { @@ -332,7 +332,7 @@ export interface ICredentialReqBody { name: string credentialName: string plainDataObj: ICredentialDataDecrypted - workspaceId?: string + workspaceId: string } // Decrypted credential object sent back to client @@ -351,7 +351,7 @@ export interface IApiKey { apiKey: string apiSecret: string updatedDate: Date - workspaceId?: string + workspaceId: string } export interface ICustomTemplate { @@ -365,7 +365,7 @@ export interface ICustomTemplate { badge?: string framework?: string usecases?: string - workspaceId?: string + workspaceId: string } export interface IFlowConfig { diff --git a/packages/server/src/controllers/assistants/index.ts b/packages/server/src/controllers/assistants/index.ts index 324907d0b2c..e4159bf3fa8 100644 --- a/packages/server/src/controllers/assistants/index.ts +++ b/packages/server/src/controllers/assistants/index.ts @@ -52,7 +52,14 @@ const deleteAssistant = async (req: Request, res: Response, next: NextFunction) `Error: assistantsController.deleteAssistant - id not provided!` ) } - const apiResponse = await assistantsService.deleteAssistant(req.params.id, req.query.isDeleteBoth) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: assistantsController.deleteAssistant - workspace ${workspaceId} not found!` + ) + } + const apiResponse = await assistantsService.deleteAssistant(req.params.id, req.query.isDeleteBoth, workspaceId) return res.json(apiResponse) } catch (error) { next(error) @@ -62,7 +69,14 @@ const deleteAssistant = async (req: Request, res: Response, next: NextFunction) const getAllAssistants = async (req: Request, res: Response, next: NextFunction) => { try { const type = req.query.type as AssistantType - const apiResponse = await assistantsService.getAllAssistants(type, req.user?.activeWorkspaceId) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: assistantsController.getAllAssistants - workspace ${workspaceId} not found!` + ) + } + const apiResponse = await assistantsService.getAllAssistants(workspaceId, type) return res.json(apiResponse) } catch (error) { next(error) @@ -77,7 +91,14 @@ const getAssistantById = async (req: Request, res: Response, next: NextFunction) `Error: assistantsController.getAssistantById - id not provided!` ) } - const apiResponse = await assistantsService.getAssistantById(req.params.id) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: assistantsController.getAssistantById - workspace ${workspaceId} not found!` + ) + } + const apiResponse = await assistantsService.getAssistantById(req.params.id, workspaceId) return res.json(apiResponse) } catch (error) { next(error) @@ -98,7 +119,14 @@ const updateAssistant = async (req: Request, res: Response, next: NextFunction) `Error: assistantsController.updateAssistant - body not provided!` ) } - const apiResponse = await assistantsService.updateAssistant(req.params.id, req.body) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: assistantsController.updateAssistant - workspace ${workspaceId} not found!` + ) + } + const apiResponse = await assistantsService.updateAssistant(req.params.id, req.body, workspaceId) return res.json(apiResponse) } catch (error) { next(error) @@ -116,7 +144,14 @@ const getChatModels = async (req: Request, res: Response, next: NextFunction) => const getDocumentStores = async (req: Request, res: Response, next: NextFunction) => { try { - const apiResponse = await assistantsService.getDocumentStores(req.user?.activeWorkspaceId) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: assistantsController.getDocumentStores - workspace ${workspaceId} not found!` + ) + } + const apiResponse = await assistantsService.getDocumentStores(workspaceId) return res.json(apiResponse) } catch (error) { next(error) diff --git a/packages/server/src/controllers/export-import/index.ts b/packages/server/src/controllers/export-import/index.ts index b066df0c8a8..ae2a869283a 100644 --- a/packages/server/src/controllers/export-import/index.ts +++ b/packages/server/src/controllers/export-import/index.ts @@ -5,10 +5,14 @@ import exportImportService from '../../services/export-import' const exportData = async (req: Request, res: Response, next: NextFunction) => { try { - const apiResponse = await exportImportService.exportData( - exportImportService.convertExportInput(req.body), - req.user?.activeWorkspaceId - ) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: exportImportController.exportData - workspace ${workspaceId} not found!` + ) + } + const apiResponse = await exportImportService.exportData(exportImportService.convertExportInput(req.body), workspaceId) return res.json(apiResponse) } catch (error) { next(error) diff --git a/packages/server/src/database/entities/ApiKey.ts b/packages/server/src/database/entities/ApiKey.ts index e7c1d84e55d..4778962a14f 100644 --- a/packages/server/src/database/entities/ApiKey.ts +++ b/packages/server/src/database/entities/ApiKey.ts @@ -19,6 +19,6 @@ export class ApiKey implements IApiKey { @UpdateDateColumn() updatedDate: Date - @Column({ nullable: true, type: 'text' }) - workspaceId?: string + @Column({ nullable: false, type: 'text' }) + workspaceId: string } diff --git a/packages/server/src/database/entities/Assistant.ts b/packages/server/src/database/entities/Assistant.ts index 28843213928..1d9eabbe8f1 100644 --- a/packages/server/src/database/entities/Assistant.ts +++ b/packages/server/src/database/entities/Assistant.ts @@ -27,6 +27,6 @@ export class Assistant implements IAssistant { @UpdateDateColumn() updatedDate: Date - @Column({ nullable: true, type: 'text' }) - workspaceId?: string + @Column({ nullable: false, type: 'text' }) + workspaceId: string } diff --git a/packages/server/src/database/entities/ChatFlow.ts b/packages/server/src/database/entities/ChatFlow.ts index 4c14e99c1c4..1a49b9adac4 100644 --- a/packages/server/src/database/entities/ChatFlow.ts +++ b/packages/server/src/database/entities/ChatFlow.ts @@ -51,6 +51,6 @@ export class ChatFlow implements IChatFlow { @UpdateDateColumn() updatedDate: Date - @Column({ nullable: true, type: 'text' }) - workspaceId?: string + @Column({ nullable: false, type: 'text' }) + workspaceId: string } diff --git a/packages/server/src/database/entities/Credential.ts b/packages/server/src/database/entities/Credential.ts index 2c43158c487..5cff59f49ea 100644 --- a/packages/server/src/database/entities/Credential.ts +++ b/packages/server/src/database/entities/Credential.ts @@ -24,6 +24,6 @@ export class Credential implements ICredential { @UpdateDateColumn() updatedDate: Date - @Column({ nullable: true, type: 'text' }) - workspaceId?: string + @Column({ nullable: false, type: 'text' }) + workspaceId: string } diff --git a/packages/server/src/database/entities/CustomTemplate.ts b/packages/server/src/database/entities/CustomTemplate.ts index e45719e69d4..ed99cebd3c6 100644 --- a/packages/server/src/database/entities/CustomTemplate.ts +++ b/packages/server/src/database/entities/CustomTemplate.ts @@ -27,7 +27,7 @@ export class CustomTemplate implements ICustomTemplate { @Column({ nullable: true, type: 'text' }) type?: string - @Column({ nullable: true, type: 'text' }) + @Column({ nullable: false, type: 'text' }) workspaceId: string @Column({ type: 'timestamp' }) diff --git a/packages/server/src/database/entities/Dataset.ts b/packages/server/src/database/entities/Dataset.ts index 8dd604d3d01..8acd5f2bb15 100644 --- a/packages/server/src/database/entities/Dataset.ts +++ b/packages/server/src/database/entities/Dataset.ts @@ -19,6 +19,6 @@ export class Dataset implements IDataset { @UpdateDateColumn() updatedDate: Date - @Column({ nullable: true, type: 'text' }) - workspaceId?: string + @Column({ nullable: false, type: 'text' }) + workspaceId: string } diff --git a/packages/server/src/database/entities/DocumentStore.ts b/packages/server/src/database/entities/DocumentStore.ts index 01babca474b..9a94fde52fa 100644 --- a/packages/server/src/database/entities/DocumentStore.ts +++ b/packages/server/src/database/entities/DocumentStore.ts @@ -38,6 +38,6 @@ export class DocumentStore implements IDocumentStore { @Column({ nullable: true, type: 'text' }) recordManagerConfig: string | null - @Column({ nullable: true, type: 'text' }) - workspaceId?: string + @Column({ nullable: false, type: 'text' }) + workspaceId: string } diff --git a/packages/server/src/database/entities/Evaluation.ts b/packages/server/src/database/entities/Evaluation.ts index 85128ae0173..4f23a05e3c7 100644 --- a/packages/server/src/database/entities/Evaluation.ts +++ b/packages/server/src/database/entities/Evaluation.ts @@ -36,6 +36,6 @@ export class Evaluation implements IEvaluation { @UpdateDateColumn() runDate: Date - @Column({ nullable: true, type: 'text' }) - workspaceId?: string + @Column({ nullable: false, type: 'text' }) + workspaceId: string } diff --git a/packages/server/src/database/entities/Evaluator.ts b/packages/server/src/database/entities/Evaluator.ts index 8e7f6f9b962..a14e0c9059a 100644 --- a/packages/server/src/database/entities/Evaluator.ts +++ b/packages/server/src/database/entities/Evaluator.ts @@ -23,6 +23,6 @@ export class Evaluator implements IEvaluator { @UpdateDateColumn() updatedDate: Date - @Column({ nullable: true, type: 'text' }) - workspaceId?: string + @Column({ nullable: false, type: 'text' }) + workspaceId: string } diff --git a/packages/server/src/database/entities/Execution.ts b/packages/server/src/database/entities/Execution.ts index 87885cf8a3f..eac53f6392a 100644 --- a/packages/server/src/database/entities/Execution.ts +++ b/packages/server/src/database/entities/Execution.ts @@ -42,6 +42,6 @@ export class Execution implements IExecution { @JoinColumn({ name: 'agentflowId' }) agentflow: ChatFlow - @Column({ nullable: true, type: 'text' }) - workspaceId?: string + @Column({ nullable: false, type: 'text' }) + workspaceId: string } diff --git a/packages/server/src/database/entities/Tool.ts b/packages/server/src/database/entities/Tool.ts index 3a0dcbc898a..2e35b64a685 100644 --- a/packages/server/src/database/entities/Tool.ts +++ b/packages/server/src/database/entities/Tool.ts @@ -33,6 +33,6 @@ export class Tool implements ITool { @UpdateDateColumn() updatedDate: Date - @Column({ nullable: true, type: 'text' }) - workspaceId?: string + @Column({ nullable: false, type: 'text' }) + workspaceId: string } diff --git a/packages/server/src/database/entities/Variable.ts b/packages/server/src/database/entities/Variable.ts index 6a8006dd67e..33105c0f6ed 100644 --- a/packages/server/src/database/entities/Variable.ts +++ b/packages/server/src/database/entities/Variable.ts @@ -24,6 +24,6 @@ export class Variable implements IVariable { @UpdateDateColumn() updatedDate: Date - @Column({ nullable: true, type: 'text' }) - workspaceId?: string + @Column({ nullable: false, type: 'text' }) + workspaceId: string } diff --git a/packages/server/src/services/assistants/index.ts b/packages/server/src/services/assistants/index.ts index 72dfc4a008a..0151124b9ca 100644 --- a/packages/server/src/services/assistants/index.ts +++ b/packages/server/src/services/assistants/index.ts @@ -160,11 +160,12 @@ const createAssistant = async (requestBody: any, orgId: string): Promise => { +const deleteAssistant = async (assistantId: string, isDeleteBoth: any, workspaceId: string): Promise => { try { const appServer = getRunningExpressApp() const assistant = await appServer.AppDataSource.getRepository(Assistant).findOneBy({ - id: assistantId + id: assistantId, + workspaceId: workspaceId }) if (!assistant) { throw new InternalFlowiseError(StatusCodes.NOT_FOUND, `Assistant ${assistantId} not found`) @@ -225,7 +226,7 @@ async function getAssistantsCountByOrganization(type: AssistantType, organizatio } } -const getAllAssistants = async (type?: AssistantType, workspaceId?: string): Promise => { +const getAllAssistants = async (workspaceId: string, type?: AssistantType): Promise => { try { const appServer = getRunningExpressApp() if (type) { @@ -245,7 +246,7 @@ const getAllAssistants = async (type?: AssistantType, workspaceId?: string): Pro } } -const getAllAssistantsCount = async (type?: AssistantType, workspaceId?: string): Promise => { +const getAllAssistantsCount = async (workspaceId: string, type?: AssistantType): Promise => { try { const appServer = getRunningExpressApp() if (type) { @@ -265,11 +266,12 @@ const getAllAssistantsCount = async (type?: AssistantType, workspaceId?: string) } } -const getAssistantById = async (assistantId: string): Promise => { +const getAssistantById = async (assistantId: string, workspaceId: string): Promise => { try { const appServer = getRunningExpressApp() const dbResponse = await appServer.AppDataSource.getRepository(Assistant).findOneBy({ - id: assistantId + id: assistantId, + workspaceId: workspaceId }) if (!dbResponse) { throw new InternalFlowiseError(StatusCodes.NOT_FOUND, `Assistant ${assistantId} not found`) @@ -283,11 +285,12 @@ const getAssistantById = async (assistantId: string): Promise => { } } -const updateAssistant = async (assistantId: string, requestBody: any): Promise => { +const updateAssistant = async (assistantId: string, requestBody: any, workspaceId: string): Promise => { try { const appServer = getRunningExpressApp() const assistant = await appServer.AppDataSource.getRepository(Assistant).findOneBy({ - id: assistantId + id: assistantId, + workspaceId: workspaceId }) if (!assistant) { @@ -461,7 +464,7 @@ const getChatModels = async (): Promise => { } } -const getDocumentStores = async (activeWorkspaceId?: string): Promise => { +const getDocumentStores = async (activeWorkspaceId: string): Promise => { try { const appServer = getRunningExpressApp() const stores = await appServer.AppDataSource.getRepository(DocumentStore).findBy(getWorkspaceSearchOptions(activeWorkspaceId)) diff --git a/packages/server/src/services/export-import/index.ts b/packages/server/src/services/export-import/index.ts index e2e39ead283..c27a0d382b8 100644 --- a/packages/server/src/services/export-import/index.ts +++ b/packages/server/src/services/export-import/index.ts @@ -88,7 +88,7 @@ const convertExportInput = (body: any): ExportInput => { } const FileDefaultName = 'ExportData.json' -const exportData = async (exportInput: ExportInput, activeWorkspaceId?: string): Promise<{ FileDefaultName: string } & ExportData> => { +const exportData = async (exportInput: ExportInput, activeWorkspaceId: string): Promise<{ FileDefaultName: string } & ExportData> => { try { let AgentFlow: ChatFlow[] | { data: ChatFlow[]; total: number } = exportInput.agentflow === true ? await chatflowService.getAllChatflows('MULTIAGENT', activeWorkspaceId) : [] @@ -99,17 +99,17 @@ const exportData = async (exportInput: ExportInput, activeWorkspaceId?: string): AgentFlowV2 = 'data' in AgentFlowV2 ? AgentFlowV2.data : AgentFlowV2 let AssistantCustom: Assistant[] = - exportInput.assistantCustom === true ? await assistantService.getAllAssistants('CUSTOM', activeWorkspaceId) : [] + exportInput.assistantCustom === true ? await assistantService.getAllAssistants(activeWorkspaceId, 'CUSTOM') : [] let AssistantFlow: ChatFlow[] | { data: ChatFlow[]; total: number } = exportInput.assistantCustom === true ? await chatflowService.getAllChatflows('ASSISTANT', activeWorkspaceId) : [] AssistantFlow = 'data' in AssistantFlow ? AssistantFlow.data : AssistantFlow let AssistantOpenAI: Assistant[] = - exportInput.assistantOpenAI === true ? await assistantService.getAllAssistants('OPENAI', activeWorkspaceId) : [] + exportInput.assistantOpenAI === true ? await assistantService.getAllAssistants(activeWorkspaceId, 'OPENAI') : [] let AssistantAzure: Assistant[] = - exportInput.assistantAzure === true ? await assistantService.getAllAssistants('AZURE', activeWorkspaceId) : [] + exportInput.assistantAzure === true ? await assistantService.getAllAssistants(activeWorkspaceId, 'AZURE') : [] let ChatFlow: ChatFlow[] | { data: ChatFlow[]; total: number } = exportInput.chatflow === true ? await chatflowService.getAllChatflows('CHATFLOW', activeWorkspaceId) : [] diff --git a/packages/server/src/utils/index.ts b/packages/server/src/utils/index.ts index 89aa4e3b742..78cc2e0ea05 100644 --- a/packages/server/src/utils/index.ts +++ b/packages/server/src/utils/index.ts @@ -833,7 +833,8 @@ export const getGlobalVariable = async ( value: overrideConfig.vars[propertyName], id: '', updatedDate: new Date(), - createdDate: new Date() + createdDate: new Date(), + workspaceId: 'dummy' }) } } From 29a2f7415031186bac6be612ffa957daaf8974df Mon Sep 17 00:00:00 2001 From: Vinod Kiran Date: Wed, 30 Jul 2025 15:26:12 +0530 Subject: [PATCH 3/7] Require workspace ID in various controllers and services - Updated controllers for credentials, datasets, document stores, evaluations, evaluators, and variables to enforce the presence of `workspaceId`. - Enhanced error handling to throw appropriate errors when `workspaceId` is not provided. - Modified service methods to accept `workspaceId` as a mandatory parameter for operations, ensuring consistent validation across the application. --- .../src/controllers/credentials/index.ts | 36 ++++- .../server/src/controllers/dataset/index.ts | 89 ++++++++++-- .../src/controllers/documentstore/index.ts | 100 ++++++++++++-- .../src/controllers/evaluations/index.ts | 65 +++++++-- .../src/controllers/evaluators/index.ts | 36 ++++- .../server/src/controllers/variables/index.ts | 27 +++- .../server/src/services/credentials/index.ts | 14 +- packages/server/src/services/dataset/index.ts | 39 +++--- .../src/services/documentstore/index.ts | 127 +++++++++++------- .../server/src/services/evaluations/index.ts | 50 ++++--- .../server/src/services/evaluator/index.ts | 18 +-- .../server/src/services/variables/index.ts | 11 +- 12 files changed, 469 insertions(+), 143 deletions(-) diff --git a/packages/server/src/controllers/credentials/index.ts b/packages/server/src/controllers/credentials/index.ts index 78cb4348c5e..6c6dea22a34 100644 --- a/packages/server/src/controllers/credentials/index.ts +++ b/packages/server/src/controllers/credentials/index.ts @@ -28,7 +28,14 @@ const deleteCredentials = async (req: Request, res: Response, next: NextFunction `Error: credentialsController.deleteCredentials - id not provided!` ) } - const apiResponse = await credentialsService.deleteCredentials(req.params.id) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: credentialsController.deleteCredentials - workspace ${workspaceId} not found!` + ) + } + const apiResponse = await credentialsService.deleteCredentials(req.params.id, workspaceId) return res.json(apiResponse) } catch (error) { next(error) @@ -37,7 +44,14 @@ const deleteCredentials = async (req: Request, res: Response, next: NextFunction const getAllCredentials = async (req: Request, res: Response, next: NextFunction) => { try { - const apiResponse = await credentialsService.getAllCredentials(req.query.credentialName, req.user?.activeWorkspaceId) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: credentialsController.getAllCredentials - workspace ${workspaceId} not found!` + ) + } + const apiResponse = await credentialsService.getAllCredentials(req.query.credentialName, workspaceId) return res.json(apiResponse) } catch (error) { next(error) @@ -52,7 +66,14 @@ const getCredentialById = async (req: Request, res: Response, next: NextFunction `Error: credentialsController.getCredentialById - id not provided!` ) } - const apiResponse = await credentialsService.getCredentialById(req.params.id, req.user?.activeWorkspaceId) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: credentialsController.getCredentialById - workspace ${workspaceId} not found!` + ) + } + const apiResponse = await credentialsService.getCredentialById(req.params.id, workspaceId) return res.json(apiResponse) } catch (error) { next(error) @@ -73,7 +94,14 @@ const updateCredential = async (req: Request, res: Response, next: NextFunction) `Error: credentialsController.updateCredential - body not provided!` ) } - const apiResponse = await credentialsService.updateCredential(req.params.id, req.body) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: credentialsController.updateCredential - workspace ${workspaceId} not found!` + ) + } + const apiResponse = await credentialsService.updateCredential(req.params.id, req.body, workspaceId) return res.json(apiResponse) } catch (error) { next(error) diff --git a/packages/server/src/controllers/dataset/index.ts b/packages/server/src/controllers/dataset/index.ts index d6c7531181f..0479a20de0d 100644 --- a/packages/server/src/controllers/dataset/index.ts +++ b/packages/server/src/controllers/dataset/index.ts @@ -7,7 +7,14 @@ import { getPageAndLimitParams } from '../../utils/pagination' const getAllDatasets = async (req: Request, res: Response, next: NextFunction) => { try { const { page, limit } = getPageAndLimitParams(req) - const apiResponse = await datasetService.getAllDatasets(req.user?.activeWorkspaceId, page, limit) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: datasetController.getAllDatasets - workspace ${workspaceId} not found!` + ) + } + const apiResponse = await datasetService.getAllDatasets(workspaceId, page, limit) return res.json(apiResponse) } catch (error) { next(error) @@ -20,7 +27,14 @@ const getDataset = async (req: Request, res: Response, next: NextFunction) => { throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Error: datasetService.getDataset - id not provided!`) } const { page, limit } = getPageAndLimitParams(req) - const apiResponse = await datasetService.getDataset(req.params.id, page, limit) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: datasetController.getDataset - workspace ${workspaceId} not found!` + ) + } + const apiResponse = await datasetService.getDataset(req.params.id, workspaceId, page, limit) return res.json(apiResponse) } catch (error) { next(error) @@ -33,7 +47,14 @@ const createDataset = async (req: Request, res: Response, next: NextFunction) => throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Error: datasetService.createDataset - body not provided!`) } const body = req.body - body.workspaceId = req.user?.activeWorkspaceId + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: datasetController.createDataset - workspace ${workspaceId} not found!` + ) + } + body.workspaceId = workspaceId const apiResponse = await datasetService.createDataset(body) return res.json(apiResponse) } catch (error) { @@ -49,7 +70,14 @@ const updateDataset = async (req: Request, res: Response, next: NextFunction) => if (typeof req.params === 'undefined' || !req.params.id) { throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Error: datasetService.updateDataset - id not provided!`) } - const apiResponse = await datasetService.updateDataset(req.params.id, req.body) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: datasetController.updateDataset - workspace ${workspaceId} not found!` + ) + } + const apiResponse = await datasetService.updateDataset(req.params.id, req.body, workspaceId) return res.json(apiResponse) } catch (error) { next(error) @@ -61,7 +89,14 @@ const deleteDataset = async (req: Request, res: Response, next: NextFunction) => if (typeof req.params === 'undefined' || !req.params.id) { throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Error: datasetService.deleteDataset - id not provided!`) } - const apiResponse = await datasetService.deleteDataset(req.params.id) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: datasetController.deleteDataset - workspace ${workspaceId} not found!` + ) + } + const apiResponse = await datasetService.deleteDataset(req.params.id, workspaceId) return res.json(apiResponse) } catch (error) { next(error) @@ -76,6 +111,14 @@ const addDatasetRow = async (req: Request, res: Response, next: NextFunction) => if (!req.body.datasetId) { throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Error: datasetService.addDatasetRow - datasetId not provided!`) } + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: datasetController.addDatasetRow - workspace ${workspaceId} not found!` + ) + } + req.body.workspaceId = workspaceId const apiResponse = await datasetService.addDatasetRow(req.body) return res.json(apiResponse) } catch (error) { @@ -91,6 +134,14 @@ const updateDatasetRow = async (req: Request, res: Response, next: NextFunction) if (typeof req.params === 'undefined' || !req.params.id) { throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Error: datasetService.updateDatasetRow - id not provided!`) } + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: datasetController.updateDatasetRow - workspace ${workspaceId} not found!` + ) + } + req.body.workspaceId = workspaceId const apiResponse = await datasetService.updateDatasetRow(req.params.id, req.body) return res.json(apiResponse) } catch (error) { @@ -103,7 +154,14 @@ const deleteDatasetRow = async (req: Request, res: Response, next: NextFunction) if (typeof req.params === 'undefined' || !req.params.id) { throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Error: datasetService.deleteDatasetRow - id not provided!`) } - const apiResponse = await datasetService.deleteDatasetRow(req.params.id) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: datasetController.deleteDatasetRow - workspace ${workspaceId} not found!` + ) + } + const apiResponse = await datasetService.deleteDatasetRow(req.params.id, workspaceId) return res.json(apiResponse) } catch (error) { next(error) @@ -113,7 +171,14 @@ const deleteDatasetRow = async (req: Request, res: Response, next: NextFunction) const patchDeleteRows = async (req: Request, res: Response, next: NextFunction) => { try { const ids = req.body.ids ?? [] - const apiResponse = await datasetService.patchDeleteRows(ids) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: datasetController.patchDeleteRows - workspace ${workspaceId} not found!` + ) + } + const apiResponse = await datasetService.patchDeleteRows(ids, workspaceId) return res.json(apiResponse) } catch (error) { next(error) @@ -125,8 +190,14 @@ const reorderDatasetRow = async (req: Request, res: Response, next: NextFunction if (!req.body) { throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Error: datasetService.reorderDatasetRow - body not provided!`) } - - const apiResponse = await datasetService.reorderDatasetRow(req.body.datasetId, req.body.rows) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: datasetController.reorderDatasetRow - workspace ${workspaceId} not found!` + ) + } + const apiResponse = await datasetService.reorderDatasetRow(req.body.datasetId, req.body.rows, workspaceId) return res.json(apiResponse) } catch (error) { next(error) diff --git a/packages/server/src/controllers/documentstore/index.ts b/packages/server/src/controllers/documentstore/index.ts index 9d19373b436..1ac4f439575 100644 --- a/packages/server/src/controllers/documentstore/index.ts +++ b/packages/server/src/controllers/documentstore/index.ts @@ -27,7 +27,12 @@ const createDocumentStore = async (req: Request, res: Response, next: NextFuncti const body = req.body body.workspaceId = req.user?.activeWorkspaceId - + if (!body.workspaceId) { + throw new InternalFlowiseError( + StatusCodes.PRECONDITION_FAILED, + `Error: documentStoreController.createDocumentStore - workspaceId not provided!` + ) + } const docStore = DocumentStoreDTO.toEntity(body) const apiResponse = await documentStoreService.createDocumentStore(docStore, orgId) return res.json(apiResponse) @@ -40,7 +45,14 @@ const getAllDocumentStores = async (req: Request, res: Response, next: NextFunct try { const { page, limit } = getPageAndLimitParams(req) - const apiResponse: any = await documentStoreService.getAllDocumentStores(req.user?.activeWorkspaceId, page, limit) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.PRECONDITION_FAILED, + `Error: documentStoreController.getAllDocumentStores - workspaceId not provided!` + ) + } + const apiResponse: any = await documentStoreService.getAllDocumentStores(workspaceId, page, limit) if (apiResponse?.total >= 0) { return res.json({ total: apiResponse.total, @@ -102,9 +114,16 @@ const getDocumentStoreById = async (req: Request, res: Response, next: NextFunct `Error: documentStoreController.getDocumentStoreById - id not provided!` ) } - const apiResponse = await documentStoreService.getDocumentStoreById(req.params.id) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.PRECONDITION_FAILED, + `Error: documentStoreController.getDocumentStoreById - workspaceId not provided!` + ) + } + const apiResponse = await documentStoreService.getDocumentStoreById(req.params.id, workspaceId) if (apiResponse && apiResponse.whereUsed) { - apiResponse.whereUsed = JSON.stringify(await documentStoreService.getUsedChatflowNames(apiResponse)) + apiResponse.whereUsed = JSON.stringify(await documentStoreService.getUsedChatflowNames(apiResponse, workspaceId)) } return res.json(DocumentStoreDTO.fromEntity(apiResponse)) } catch (error) { @@ -126,12 +145,20 @@ const getDocumentStoreFileChunks = async (req: Request, res: Response, next: Nex `Error: documentStoreController.getDocumentStoreFileChunks - fileId not provided!` ) } + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.PRECONDITION_FAILED, + `Error: documentStoreController.getDocumentStoreFileChunks - workspaceId not provided!` + ) + } const appDataSource = getRunningExpressApp().AppDataSource const page = req.params.pageNo ? parseInt(req.params.pageNo) : 1 const apiResponse = await documentStoreService.getDocumentStoreFileChunks( appDataSource, req.params.storeId, req.params.fileId, + workspaceId, page ) return res.json(apiResponse) @@ -160,10 +187,18 @@ const deleteDocumentStoreFileChunk = async (req: Request, res: Response, next: N `Error: documentStoreController.deleteDocumentStoreFileChunk - chunkId not provided!` ) } + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.PRECONDITION_FAILED, + `Error: documentStoreController.deleteDocumentStoreFileChunk - workspaceId not provided!` + ) + } const apiResponse = await documentStoreService.deleteDocumentStoreFileChunk( req.params.storeId, req.params.loaderId, - req.params.chunkId + req.params.chunkId, + workspaceId ) return res.json(apiResponse) } catch (error) { @@ -198,12 +233,20 @@ const editDocumentStoreFileChunk = async (req: Request, res: Response, next: Nex `Error: documentStoreController.editDocumentStoreFileChunk - body not provided!` ) } + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.PRECONDITION_FAILED, + `Error: documentStoreController.editDocumentStoreFileChunk - workspaceId not provided!` + ) + } const apiResponse = await documentStoreService.editDocumentStoreFileChunk( req.params.storeId, req.params.loaderId, req.params.chunkId, body.pageContent, - body.metadata + body.metadata, + workspaceId ) return res.json(apiResponse) } catch (error) { @@ -221,7 +264,14 @@ const saveProcessingLoader = async (req: Request, res: Response, next: NextFunct ) } const body = req.body - const apiResponse = await documentStoreService.saveProcessingLoader(appServer.AppDataSource, body) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.PRECONDITION_FAILED, + `Error: documentStoreController.saveProcessingLoader - workspaceId not provided!` + ) + } + const apiResponse = await documentStoreService.saveProcessingLoader(appServer.AppDataSource, body, workspaceId) return res.json(apiResponse) } catch (error) { next(error) @@ -289,7 +339,14 @@ const updateDocumentStore = async (req: Request, res: Response, next: NextFuncti `Error: documentStoreController.updateDocumentStore - body not provided!` ) } - const store = await documentStoreService.getDocumentStoreById(req.params.id) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.PRECONDITION_FAILED, + `Error: documentStoreController.updateDocumentStore - workspaceId not provided!` + ) + } + const store = await documentStoreService.getDocumentStoreById(req.params.id, workspaceId) if (!store) { throw new InternalFlowiseError( StatusCodes.NOT_FOUND, @@ -449,7 +506,14 @@ const deleteVectorStoreFromStore = async (req: Request, res: Response, next: Nex `Error: documentStoreController.deleteVectorStoreFromStore - storeId not provided!` ) } - const apiResponse = await documentStoreService.deleteVectorStoreFromStore(req.params.storeId) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.PRECONDITION_FAILED, + `Error: documentStoreController.deleteVectorStoreFromStore - workspaceId not provided!` + ) + } + const apiResponse = await documentStoreService.deleteVectorStoreFromStore(req.params.storeId, workspaceId) return res.json(apiResponse) } catch (error) { next(error) @@ -463,7 +527,14 @@ const saveVectorStoreConfig = async (req: Request, res: Response, next: NextFunc } const body = req.body const appDataSource = getRunningExpressApp().AppDataSource - const apiResponse = await documentStoreService.saveVectorStoreConfig(appDataSource, body) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.PRECONDITION_FAILED, + `Error: documentStoreController.saveVectorStoreConfig - workspaceId not provided!` + ) + } + const apiResponse = await documentStoreService.saveVectorStoreConfig(appDataSource, body, true, workspaceId) return res.json(apiResponse) } catch (error) { next(error) @@ -476,7 +547,14 @@ const updateVectorStoreConfigOnly = async (req: Request, res: Response, next: Ne throw new Error('Error: documentStoreController.updateVectorStoreConfigOnly - body not provided!') } const body = req.body - const apiResponse = await documentStoreService.updateVectorStoreConfigOnly(body) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.PRECONDITION_FAILED, + `Error: documentStoreController.updateVectorStoreConfigOnly - workspaceId not provided!` + ) + } + const apiResponse = await documentStoreService.updateVectorStoreConfigOnly(body, workspaceId) return res.json(apiResponse) } catch (error) { next(error) diff --git a/packages/server/src/controllers/evaluations/index.ts b/packages/server/src/controllers/evaluations/index.ts index 4cde7615804..b38213aa0b7 100644 --- a/packages/server/src/controllers/evaluations/index.ts +++ b/packages/server/src/controllers/evaluations/index.ts @@ -31,7 +31,7 @@ const createEvaluation = async (req: Request, res: Response, next: NextFunction) const httpProtocol = req.get('x-forwarded-proto') || req.get('X-Forwarded-Proto') || req.protocol const baseURL = `${httpProtocol}://${req.get('host')}` - const apiResponse = await evaluationsService.createEvaluation(body, baseURL, orgId) + const apiResponse = await evaluationsService.createEvaluation(body, baseURL, orgId, workspaceId) return res.json(apiResponse) } catch (error) { next(error) @@ -47,9 +47,16 @@ const runAgain = async (req: Request, res: Response, next: NextFunction) => { if (!orgId) { throw new InternalFlowiseError(StatusCodes.NOT_FOUND, `Error: evaluationsService.runAgain - organization ${orgId} not found!`) } + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: evaluationsService.runAgain - workspace ${workspaceId} not found!` + ) + } const httpProtocol = req.get('x-forwarded-proto') || req.get('X-Forwarded-Proto') || req.protocol const baseURL = `${httpProtocol}://${req.get('host')}` - const apiResponse = await evaluationsService.runAgain(req.params.id, baseURL, orgId) + const apiResponse = await evaluationsService.runAgain(req.params.id, baseURL, orgId, workspaceId) return res.json(apiResponse) } catch (error) { next(error) @@ -61,7 +68,14 @@ const getEvaluation = async (req: Request, res: Response, next: NextFunction) => if (typeof req.params === 'undefined' || !req.params.id) { throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Error: evaluationsService.getEvaluation - id not provided!`) } - const apiResponse = await evaluationsService.getEvaluation(req.params.id) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: evaluationsService.getEvaluation - workspace ${workspaceId} not found!` + ) + } + const apiResponse = await evaluationsService.getEvaluation(req.params.id, workspaceId) return res.json(apiResponse) } catch (error) { next(error) @@ -73,7 +87,14 @@ const deleteEvaluation = async (req: Request, res: Response, next: NextFunction) if (typeof req.params === 'undefined' || !req.params.id) { throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Error: evaluationsService.deleteEvaluation - id not provided!`) } - const apiResponse = await evaluationsService.deleteEvaluation(req.params.id, req.user?.activeWorkspaceId) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: evaluationsService.deleteEvaluation - workspace ${workspaceId} not found!` + ) + } + const apiResponse = await evaluationsService.deleteEvaluation(req.params.id, workspaceId) return res.json(apiResponse) } catch (error) { next(error) @@ -83,7 +104,14 @@ const deleteEvaluation = async (req: Request, res: Response, next: NextFunction) const getAllEvaluations = async (req: Request, res: Response, next: NextFunction) => { try { const { page, limit } = getPageAndLimitParams(req) - const apiResponse = await evaluationsService.getAllEvaluations(req.user?.activeWorkspaceId, page, limit) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: evaluationsService.getAllEvaluations - workspace ${workspaceId} not found!` + ) + } + const apiResponse = await evaluationsService.getAllEvaluations(workspaceId, page, limit) return res.json(apiResponse) } catch (error) { next(error) @@ -95,7 +123,14 @@ const isOutdated = async (req: Request, res: Response, next: NextFunction) => { if (typeof req.params === 'undefined' || !req.params.id) { throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Error: evaluationsService.isOutdated - id not provided!`) } - const apiResponse = await evaluationsService.isOutdated(req.params.id) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: evaluationsService.isOutdated - workspace ${workspaceId} not found!` + ) + } + const apiResponse = await evaluationsService.isOutdated(req.params.id, workspaceId) return res.json(apiResponse) } catch (error) { next(error) @@ -107,7 +142,14 @@ const getVersions = async (req: Request, res: Response, next: NextFunction) => { if (typeof req.params === 'undefined' || !req.params.id) { throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Error: evaluationsService.getVersions - id not provided!`) } - const apiResponse = await evaluationsService.getVersions(req.params.id) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: evaluationsService.getVersions - workspace ${workspaceId} not found!` + ) + } + const apiResponse = await evaluationsService.getVersions(req.params.id, workspaceId) return res.json(apiResponse) } catch (error) { next(error) @@ -118,7 +160,14 @@ const patchDeleteEvaluations = async (req: Request, res: Response, next: NextFun try { const ids = req.body.ids ?? [] const isDeleteAllVersion = req.body.isDeleteAllVersion ?? false - const apiResponse = await evaluationsService.patchDeleteEvaluations(ids, isDeleteAllVersion, req.user?.activeWorkspaceId) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: evaluationsService.patchDeleteEvaluations - workspace ${workspaceId} not found!` + ) + } + const apiResponse = await evaluationsService.patchDeleteEvaluations(ids, workspaceId, isDeleteAllVersion) return res.json(apiResponse) } catch (error) { next(error) diff --git a/packages/server/src/controllers/evaluators/index.ts b/packages/server/src/controllers/evaluators/index.ts index 1f151c37c73..5f864a85c5e 100644 --- a/packages/server/src/controllers/evaluators/index.ts +++ b/packages/server/src/controllers/evaluators/index.ts @@ -7,7 +7,14 @@ import { getPageAndLimitParams } from '../../utils/pagination' const getAllEvaluators = async (req: Request, res: Response, next: NextFunction) => { try { const { page, limit } = getPageAndLimitParams(req) - const apiResponse = await evaluatorService.getAllEvaluators(req.user?.activeWorkspaceId, page, limit) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: evaluatorService.getAllEvaluators - workspace ${workspaceId} not found!` + ) + } + const apiResponse = await evaluatorService.getAllEvaluators(workspaceId, page, limit) return res.json(apiResponse) } catch (error) { next(error) @@ -19,7 +26,14 @@ const getEvaluator = async (req: Request, res: Response, next: NextFunction) => if (typeof req.params === 'undefined' || !req.params.id) { throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Error: evaluatorService.getEvaluator - id not provided!`) } - const apiResponse = await evaluatorService.getEvaluator(req.params.id) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: evaluatorService.getEvaluator - workspace ${workspaceId} not found!` + ) + } + const apiResponse = await evaluatorService.getEvaluator(req.params.id, workspaceId) return res.json(apiResponse) } catch (error) { next(error) @@ -48,7 +62,14 @@ const updateEvaluator = async (req: Request, res: Response, next: NextFunction) if (typeof req.params === 'undefined' || !req.params.id) { throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Error: evaluatorService.updateEvaluator - id not provided!`) } - const apiResponse = await evaluatorService.updateEvaluator(req.params.id, req.body) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: evaluatorService.updateEvaluator - workspace ${workspaceId} not found!` + ) + } + const apiResponse = await evaluatorService.updateEvaluator(req.params.id, req.body, workspaceId) return res.json(apiResponse) } catch (error) { next(error) @@ -60,7 +81,14 @@ const deleteEvaluator = async (req: Request, res: Response, next: NextFunction) if (typeof req.params === 'undefined' || !req.params.id) { throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Error: evaluatorService.deleteEvaluator - id not provided!`) } - const apiResponse = await evaluatorService.deleteEvaluator(req.params.id) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: evaluatorService.deleteEvaluator - workspace ${workspaceId} not found!` + ) + } + const apiResponse = await evaluatorService.deleteEvaluator(req.params.id, workspaceId) return res.json(apiResponse) } catch (error) { next(error) diff --git a/packages/server/src/controllers/variables/index.ts b/packages/server/src/controllers/variables/index.ts index 42b58603ecc..3f8455410bf 100644 --- a/packages/server/src/controllers/variables/index.ts +++ b/packages/server/src/controllers/variables/index.ts @@ -37,7 +37,14 @@ const deleteVariable = async (req: Request, res: Response, next: NextFunction) = if (typeof req.params === 'undefined' || !req.params.id) { throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, 'Error: variablesController.deleteVariable - id not provided!') } - const apiResponse = await variablesService.deleteVariable(req.params.id) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: variablesController.deleteVariable - workspace ${workspaceId} not found!` + ) + } + const apiResponse = await variablesService.deleteVariable(req.params.id, workspaceId) return res.json(apiResponse) } catch (error) { next(error) @@ -47,7 +54,14 @@ const deleteVariable = async (req: Request, res: Response, next: NextFunction) = const getAllVariables = async (req: Request, res: Response, next: NextFunction) => { try { const { page, limit } = getPageAndLimitParams(req) - const apiResponse = await variablesService.getAllVariables(req.user?.activeWorkspaceId, page, limit) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: variablesController.getAllVariables - workspace ${workspaceId} not found!` + ) + } + const apiResponse = await variablesService.getAllVariables(workspaceId, page, limit) return res.json(apiResponse) } catch (error) { next(error) @@ -65,7 +79,14 @@ const updateVariable = async (req: Request, res: Response, next: NextFunction) = 'Error: variablesController.updateVariable - body not provided!' ) } - const variable = await variablesService.getVariableById(req.params.id) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: variablesController.updateVariable - workspace ${workspaceId} not found!` + ) + } + const variable = await variablesService.getVariableById(req.params.id, workspaceId) if (!variable) { return res.status(404).send(`Variable ${req.params.id} not found in the database`) } diff --git a/packages/server/src/services/credentials/index.ts b/packages/server/src/services/credentials/index.ts index 89219cabe26..e07c32da3af 100644 --- a/packages/server/src/services/credentials/index.ts +++ b/packages/server/src/services/credentials/index.ts @@ -31,10 +31,10 @@ const createCredential = async (requestBody: any) => { } // Delete all credentials from chatflowid -const deleteCredentials = async (credentialId: string): Promise => { +const deleteCredentials = async (credentialId: string, workspaceId: string): Promise => { try { const appServer = getRunningExpressApp() - const dbResponse = await appServer.AppDataSource.getRepository(Credential).delete({ id: credentialId }) + const dbResponse = await appServer.AppDataSource.getRepository(Credential).delete({ id: credentialId, workspaceId: workspaceId }) if (!dbResponse) { throw new InternalFlowiseError(StatusCodes.NOT_FOUND, `Credential ${credentialId} not found`) } @@ -47,7 +47,7 @@ const deleteCredentials = async (credentialId: string): Promise => { } } -const getAllCredentials = async (paramCredentialName: any, workspaceId?: string) => { +const getAllCredentials = async (paramCredentialName: any, workspaceId: string) => { try { const appServer = getRunningExpressApp() let dbResponse = [] @@ -124,7 +124,7 @@ const getAllCredentials = async (paramCredentialName: any, workspaceId?: string) } } -const getCredentialById = async (credentialId: string, workspaceId?: string): Promise => { +const getCredentialById = async (credentialId: string, workspaceId: string): Promise => { try { const appServer = getRunningExpressApp() const credential = await appServer.AppDataSource.getRepository(Credential).findOneBy({ @@ -165,11 +165,12 @@ const getCredentialById = async (credentialId: string, workspaceId?: string): Pr } } -const updateCredential = async (credentialId: string, requestBody: any): Promise => { +const updateCredential = async (credentialId: string, requestBody: any, workspaceId: string): Promise => { try { const appServer = getRunningExpressApp() const credential = await appServer.AppDataSource.getRepository(Credential).findOneBy({ - id: credentialId + id: credentialId, + workspaceId: workspaceId }) if (!credential) { throw new InternalFlowiseError(StatusCodes.NOT_FOUND, `Credential ${credentialId} not found`) @@ -177,6 +178,7 @@ const updateCredential = async (credentialId: string, requestBody: any): Promise const decryptedCredentialData = await decryptCredentialData(credential.encryptedData) requestBody.plainDataObj = { ...decryptedCredentialData, ...requestBody.plainDataObj } const updateCredential = await transformToCredentialEntity(requestBody) + updateCredential.workspaceId = workspaceId await appServer.AppDataSource.getRepository(Credential).merge(credential, updateCredential) const dbResponse = await appServer.AppDataSource.getRepository(Credential).save(credential) return dbResponse diff --git a/packages/server/src/services/dataset/index.ts b/packages/server/src/services/dataset/index.ts index 351919e6b23..4042e420f40 100644 --- a/packages/server/src/services/dataset/index.ts +++ b/packages/server/src/services/dataset/index.ts @@ -9,7 +9,7 @@ import { In } from 'typeorm' import csv from 'csv-parser' -const getAllDatasets = async (workspaceId?: string, page: number = -1, limit: number = -1) => { +const getAllDatasets = async (workspaceId: string, page: number = -1, limit: number = -1) => { try { const appServer = getRunningExpressApp() const queryBuilder = appServer.AppDataSource.getRepository(Dataset).createQueryBuilder('ds').orderBy('ds.updatedDate', 'DESC') @@ -43,11 +43,12 @@ const getAllDatasets = async (workspaceId?: string, page: number = -1, limit: nu } } -const getDataset = async (id: string, page: number = -1, limit: number = -1) => { +const getDataset = async (id: string, workspaceId: string, page: number = -1, limit: number = -1) => { try { const appServer = getRunningExpressApp() const dataset = await appServer.AppDataSource.getRepository(Dataset).findOneBy({ - id: id + id: id, + workspaceId: workspaceId }) const queryBuilder = appServer.AppDataSource.getRepository(DatasetRow).createQueryBuilder('dsr').orderBy('dsr.sequenceNo', 'ASC') queryBuilder.andWhere('dsr.datasetId = :datasetId', { datasetId: id }) @@ -88,7 +89,7 @@ const getDataset = async (id: string, page: number = -1, limit: number = -1) => } } -const reorderDatasetRow = async (datasetId: string, rows: any[]) => { +const reorderDatasetRow = async (datasetId: string, rows: any[], workspaceId: string) => { try { const appServer = getRunningExpressApp() await appServer.AppDataSource.transaction(async (entityManager) => { @@ -102,7 +103,7 @@ const reorderDatasetRow = async (datasetId: string, rows: any[]) => { item.sequenceNo = row.sequenceNo await entityManager.getRepository(DatasetRow).save(item) } - await changeUpdateOnDataset(datasetId, entityManager) + await changeUpdateOnDataset(datasetId, workspaceId, entityManager) }) return { message: 'Dataset row reordered successfully' } } catch (error) { @@ -211,11 +212,12 @@ const createDataset = async (body: any) => { } // Update dataset -const updateDataset = async (id: string, body: any) => { +const updateDataset = async (id: string, body: any, workspaceId: string) => { try { const appServer = getRunningExpressApp() const dataset = await appServer.AppDataSource.getRepository(Dataset).findOneBy({ - id: id + id: id, + workspaceId: workspaceId }) if (!dataset) throw new InternalFlowiseError(StatusCodes.NOT_FOUND, `Dataset ${id} not found`) @@ -230,10 +232,10 @@ const updateDataset = async (id: string, body: any) => { } // Delete dataset via id -const deleteDataset = async (id: string) => { +const deleteDataset = async (id: string, workspaceId: string) => { try { const appServer = getRunningExpressApp() - const result = await appServer.AppDataSource.getRepository(Dataset).delete({ id: id }) + const result = await appServer.AppDataSource.getRepository(Dataset).delete({ id: id, workspaceId: workspaceId }) // delete all rows for this dataset await appServer.AppDataSource.getRepository(DatasetRow).delete({ datasetId: id }) @@ -250,7 +252,7 @@ const addDatasetRow = async (body: any) => { const appServer = getRunningExpressApp() if (body.csvFile) { await _csvToDatasetRows(body.datasetId, body.csvFile, body.firstRowHeaders) - await changeUpdateOnDataset(body.datasetId) + await changeUpdateOnDataset(body.datasetId, body.workspaceId) return { message: 'Dataset rows added successfully' } } else { // get the max value first @@ -272,7 +274,7 @@ const addDatasetRow = async (body: any) => { newDs.sequenceNo = sequenceNo === 0 ? sequenceNo : sequenceNo + 1 const row = appServer.AppDataSource.getRepository(DatasetRow).create(newDs) const result = await appServer.AppDataSource.getRepository(DatasetRow).save(row) - await changeUpdateOnDataset(body.datasetId) + await changeUpdateOnDataset(body.datasetId, body.workspaceId) return result } } catch (error) { @@ -283,10 +285,11 @@ const addDatasetRow = async (body: any) => { } } -const changeUpdateOnDataset = async (id: string, entityManager?: any) => { +const changeUpdateOnDataset = async (id: string, workspaceId: string, entityManager?: any) => { const appServer = getRunningExpressApp() const dataset = await appServer.AppDataSource.getRepository(Dataset).findOneBy({ - id: id + id: id, + workspaceId: workspaceId }) if (!dataset) throw new InternalFlowiseError(StatusCodes.NOT_FOUND, `Dataset ${id} not found`) @@ -311,7 +314,7 @@ const updateDatasetRow = async (id: string, body: any) => { Object.assign(updateItem, body) appServer.AppDataSource.getRepository(DatasetRow).merge(item, updateItem) const result = await appServer.AppDataSource.getRepository(DatasetRow).save(item) - await changeUpdateOnDataset(body.datasetId) + await changeUpdateOnDataset(body.datasetId, body.workspaceId) return result } catch (error) { throw new InternalFlowiseError( @@ -322,7 +325,7 @@ const updateDatasetRow = async (id: string, body: any) => { } // Delete dataset row via id -const deleteDatasetRow = async (id: string) => { +const deleteDatasetRow = async (id: string, workspaceId: string) => { try { const appServer = getRunningExpressApp() return await appServer.AppDataSource.transaction(async (entityManager) => { @@ -332,7 +335,7 @@ const deleteDatasetRow = async (id: string) => { if (!item) throw new InternalFlowiseError(StatusCodes.NOT_FOUND, `Dataset Row ${id} not found`) const result = await entityManager.getRepository(DatasetRow).delete({ id: id }) - await changeUpdateOnDataset(item.datasetId, entityManager) + await changeUpdateOnDataset(item.datasetId, workspaceId, entityManager) return result }) } catch (error) { @@ -344,7 +347,7 @@ const deleteDatasetRow = async (id: string) => { } // Delete dataset rows via ids -const patchDeleteRows = async (ids: string[] = []) => { +const patchDeleteRows = async (ids: string[] = [], workspaceId: string) => { try { const appServer = getRunningExpressApp() const datasetItemsToBeDeleted = await appServer.AppDataSource.getRepository(DatasetRow).find({ @@ -356,7 +359,7 @@ const patchDeleteRows = async (ids: string[] = []) => { const datasetIds = [...new Set(datasetItemsToBeDeleted.map((item) => item.datasetId))] for (const datasetId of datasetIds) { - await changeUpdateOnDataset(datasetId) + await changeUpdateOnDataset(datasetId, workspaceId) } return dbResponse } catch (error) { diff --git a/packages/server/src/services/documentstore/index.ts b/packages/server/src/services/documentstore/index.ts index a9a12fd47ce..ccbaf6b351e 100644 --- a/packages/server/src/services/documentstore/index.ts +++ b/packages/server/src/services/documentstore/index.ts @@ -77,7 +77,7 @@ const createDocumentStore = async (newDocumentStore: DocumentStore, orgId: strin } } -const getAllDocumentStores = async (workspaceId?: string, page: number = -1, limit: number = -1) => { +const getAllDocumentStores = async (workspaceId: string, page: number = -1, limit: number = -1) => { try { const appServer = getRunningExpressApp() const queryBuilder = appServer.AppDataSource.getRepository(DocumentStore) @@ -88,7 +88,7 @@ const getAllDocumentStores = async (workspaceId?: string, page: number = -1, lim queryBuilder.skip((page - 1) * limit) queryBuilder.take(limit) } - if (workspaceId) queryBuilder.andWhere('doc_store.workspaceId = :workspaceId', { workspaceId }) + queryBuilder.andWhere('doc_store.workspaceId = :workspaceId', { workspaceId }) const [data, total] = await queryBuilder.getManyAndCount() @@ -172,11 +172,12 @@ const deleteLoaderFromDocumentStore = async ( } } -const getDocumentStoreById = async (storeId: string) => { +const getDocumentStoreById = async (storeId: string, workspaceId: string) => { try { const appServer = getRunningExpressApp() const entity = await appServer.AppDataSource.getRepository(DocumentStore).findOneBy({ - id: storeId + id: storeId, + workspaceId: workspaceId }) if (!entity) { throw new InternalFlowiseError( @@ -193,7 +194,7 @@ const getDocumentStoreById = async (storeId: string) => { } } -const getUsedChatflowNames = async (entity: DocumentStore) => { +const getUsedChatflowNames = async (entity: DocumentStore, workspaceId: string) => { try { const appServer = getRunningExpressApp() if (entity.whereUsed) { @@ -201,7 +202,7 @@ const getUsedChatflowNames = async (entity: DocumentStore) => { const updatedWhereUsed: IDocumentStoreWhereUsed[] = [] for (let i = 0; i < whereUsed.length; i++) { const associatedChatflow = await appServer.AppDataSource.getRepository(ChatFlow).findOne({ - where: { id: whereUsed[i] }, + where: { id: whereUsed[i], workspaceId: workspaceId }, select: ['id', 'name'] }) if (associatedChatflow) { @@ -223,10 +224,17 @@ const getUsedChatflowNames = async (entity: DocumentStore) => { } // Get chunks for a specific loader or store -const getDocumentStoreFileChunks = async (appDataSource: DataSource, storeId: string, docId: string, pageNo: number = 1) => { +const getDocumentStoreFileChunks = async ( + appDataSource: DataSource, + storeId: string, + docId: string, + workspaceId: string, + pageNo: number = 1 +) => { try { const entity = await appDataSource.getRepository(DocumentStore).findOneBy({ - id: storeId + id: storeId, + workspaceId: workspaceId }) if (!entity) { throw new InternalFlowiseError( @@ -303,28 +311,30 @@ const getDocumentStoreFileChunks = async (appDataSource: DataSource, storeId: st } } -const deleteDocumentStore = async (storeId: string, orgId: string, workspaceId: string, usageCacheManager: UsageCacheManager) => { +const deleteDocumentStore = async ( + storeId: string, + orgId: string, + workspaceId: string, + usageCacheManager: UsageCacheManager, + isDeleteBoth: boolean = false +) => { try { const appServer = getRunningExpressApp() - // delete all the chunks associated with the store - await appServer.AppDataSource.getRepository(DocumentStoreFileChunk).delete({ - storeId: storeId - }) - // now delete the files associated with the store const entity = await appServer.AppDataSource.getRepository(DocumentStore).findOneBy({ - id: storeId + id: storeId, + workspaceId: workspaceId }) if (!entity) { throw new InternalFlowiseError(StatusCodes.NOT_FOUND, `Document store ${storeId} not found`) } - if (workspaceId) { - if (entity?.workspaceId !== workspaceId) { - throw new Error('Unauthorized access') - } - } + // delete all the chunks associated with the store + await appServer.AppDataSource.getRepository(DocumentStoreFileChunk).delete({ + storeId: storeId + }) + // now delete the files associated with the store try { const { totalSize } = await removeFilesFromStorage(orgId, DOCUMENT_STORE_BASE_FOLDER, entity.id) await updateStorageUsage(orgId, workspaceId, totalSize, usageCacheManager) @@ -351,11 +361,12 @@ const deleteDocumentStore = async (storeId: string, orgId: string, workspaceId: } } -const deleteDocumentStoreFileChunk = async (storeId: string, docId: string, chunkId: string) => { +const deleteDocumentStoreFileChunk = async (storeId: string, docId: string, chunkId: string, workspaceId: string) => { try { const appServer = getRunningExpressApp() const entity = await appServer.AppDataSource.getRepository(DocumentStore).findOneBy({ - id: storeId + id: storeId, + workspaceId: workspaceId }) if (!entity) { throw new InternalFlowiseError(StatusCodes.NOT_FOUND, `Document store ${storeId} not found`) @@ -377,7 +388,7 @@ const deleteDocumentStoreFileChunk = async (storeId: string, docId: string, chun found.totalChars -= tbdChunk.pageContent.length entity.loaders = JSON.stringify(loaders) await appServer.AppDataSource.getRepository(DocumentStore).save(entity) - return getDocumentStoreFileChunks(appServer.AppDataSource, storeId, docId) + return getDocumentStoreFileChunks(appServer.AppDataSource, storeId, docId, workspaceId) } catch (error) { throw new InternalFlowiseError( StatusCodes.INTERNAL_SERVER_ERROR, @@ -386,13 +397,14 @@ const deleteDocumentStoreFileChunk = async (storeId: string, docId: string, chun } } -const deleteVectorStoreFromStore = async (storeId: string) => { +const deleteVectorStoreFromStore = async (storeId: string, workspaceId: string) => { try { const appServer = getRunningExpressApp() const componentNodes = appServer.nodesPool.componentNodes const entity = await appServer.AppDataSource.getRepository(DocumentStore).findOneBy({ - id: storeId + id: storeId, + workspaceId: workspaceId }) if (!entity) { throw new InternalFlowiseError(StatusCodes.NOT_FOUND, `Document store ${storeId} not found`) @@ -465,11 +477,19 @@ const deleteVectorStoreFromStore = async (storeId: string) => { } } -const editDocumentStoreFileChunk = async (storeId: string, docId: string, chunkId: string, content: string, metadata: ICommonObject) => { +const editDocumentStoreFileChunk = async ( + storeId: string, + docId: string, + chunkId: string, + content: string, + metadata: ICommonObject, + workspaceId: string +) => { try { const appServer = getRunningExpressApp() const entity = await appServer.AppDataSource.getRepository(DocumentStore).findOneBy({ - id: storeId + id: storeId, + workspaceId: workspaceId }) if (!entity) { throw new InternalFlowiseError(StatusCodes.NOT_FOUND, `Document store ${storeId} not found`) @@ -493,7 +513,7 @@ const editDocumentStoreFileChunk = async (storeId: string, docId: string, chunkI await appServer.AppDataSource.getRepository(DocumentStoreFileChunk).save(editChunk) entity.loaders = JSON.stringify(loaders) await appServer.AppDataSource.getRepository(DocumentStore).save(entity) - return getDocumentStoreFileChunks(appServer.AppDataSource, storeId, docId) + return getDocumentStoreFileChunks(appServer.AppDataSource, storeId, docId, workspaceId) } catch (error) { throw new InternalFlowiseError( StatusCodes.INTERNAL_SERVER_ERROR, @@ -717,10 +737,15 @@ export const previewChunks = async ({ appDataSource, componentNodes, data, orgId } } -const saveProcessingLoader = async (appDataSource: DataSource, data: IDocumentStoreLoaderForPreview): Promise => { +const saveProcessingLoader = async ( + appDataSource: DataSource, + data: IDocumentStoreLoaderForPreview, + workspaceId: string +): Promise => { try { const entity = await appDataSource.getRepository(DocumentStore).findOneBy({ - id: data.storeId + id: data.storeId, + workspaceId: workspaceId }) if (!entity) { throw new InternalFlowiseError( @@ -808,7 +833,8 @@ export const processLoader = async ({ usageCacheManager }: IExecuteProcessLoader) => { const entity = await appDataSource.getRepository(DocumentStore).findOneBy({ - id: data.storeId + id: data.storeId, + workspaceId: workspaceId }) if (!entity) { throw new InternalFlowiseError( @@ -816,11 +842,6 @@ export const processLoader = async ({ `Error: documentStoreServices.processLoader - Document store ${data.storeId} not found` ) } - if (workspaceId) { - if (entity?.workspaceId !== workspaceId) { - throw new Error('Unauthorized access') - } - } await _saveChunksToStorage( appDataSource, componentNodes, @@ -832,7 +853,7 @@ export const processLoader = async ({ subscriptionId, usageCacheManager ) - return getDocumentStoreFileChunks(appDataSource, data.storeId as string, docLoaderId) + return getDocumentStoreFileChunks(appDataSource, data.storeId as string, docLoaderId, workspaceId) } const processLoaderMiddleware = async ( @@ -1113,11 +1134,12 @@ const updateDocumentStoreUsage = async (chatId: string, storeId: string | undefi } } -const updateVectorStoreConfigOnly = async (data: ICommonObject) => { +const updateVectorStoreConfigOnly = async (data: ICommonObject, workspaceId: string) => { try { const appServer = getRunningExpressApp() const entity = await appServer.AppDataSource.getRepository(DocumentStore).findOneBy({ - id: data.storeId + id: data.storeId, + workspaceId: workspaceId }) if (!entity) { throw new InternalFlowiseError(StatusCodes.NOT_FOUND, `Document store ${data.storeId} not found`) @@ -1140,10 +1162,11 @@ const updateVectorStoreConfigOnly = async (data: ICommonObject) => { ) } } -const saveVectorStoreConfig = async (appDataSource: DataSource, data: ICommonObject, isStrictSave = true) => { +const saveVectorStoreConfig = async (appDataSource: DataSource, data: ICommonObject, isStrictSave = true, workspaceId: string) => { try { const entity = await appDataSource.getRepository(DocumentStore).findOneBy({ - id: data.storeId + id: data.storeId, + workspaceId: workspaceId }) if (!entity) { throw new InternalFlowiseError(StatusCodes.NOT_FOUND, `Document store ${data.storeId} not found`) @@ -1209,14 +1232,23 @@ export const insertIntoVectorStore = async ({ telemetry, data, isStrictSave, - orgId + orgId, + workspaceId }: IExecuteVectorStoreInsert) => { try { - const entity = await saveVectorStoreConfig(appDataSource, data, isStrictSave) + const entity = await saveVectorStoreConfig(appDataSource, data, isStrictSave, workspaceId) entity.status = DocumentStoreStatus.UPSERTING await appDataSource.getRepository(DocumentStore).save(entity) - const indexResult = await _insertIntoVectorStoreWorkerThread(appDataSource, componentNodes, telemetry, data, isStrictSave, orgId) + const indexResult = await _insertIntoVectorStoreWorkerThread( + appDataSource, + componentNodes, + telemetry, + data, + isStrictSave, + orgId, + workspaceId + ) return indexResult } catch (error) { throw new InternalFlowiseError( @@ -1282,10 +1314,11 @@ const _insertIntoVectorStoreWorkerThread = async ( telemetry: Telemetry, data: ICommonObject, isStrictSave = true, - orgId: string + orgId: string, + workspaceId: string ) => { try { - const entity = await saveVectorStoreConfig(appDataSource, data, isStrictSave) + const entity = await saveVectorStoreConfig(appDataSource, data, isStrictSave, workspaceId) let upsertHistory: Record = {} const chatflowid = data.storeId // fake chatflowid because this is not tied to any chatflow @@ -1852,7 +1885,7 @@ const upsertDocStore = async ( } try { - const newLoader = await saveProcessingLoader(appDataSource, processData) + const newLoader = await saveProcessingLoader(appDataSource, processData, workspaceId) const result = await processLoader({ appDataSource, componentNodes, diff --git a/packages/server/src/services/evaluations/index.ts b/packages/server/src/services/evaluations/index.ts index 9195ac26f7c..3d1b13d4c9e 100644 --- a/packages/server/src/services/evaluations/index.ts +++ b/packages/server/src/services/evaluations/index.ts @@ -21,11 +21,12 @@ import evaluatorsService from '../evaluator' import { LLMEvaluationRunner } from './LLMEvaluationRunner' import { Assistant } from '../../database/entities/Assistant' -const runAgain = async (id: string, baseURL: string, orgId: string) => { +const runAgain = async (id: string, baseURL: string, orgId: string, workspaceId: string) => { try { const appServer = getRunningExpressApp() const evaluation = await appServer.AppDataSource.getRepository(Evaluation).findOneBy({ - id: id + id: id, + workspaceId: workspaceId }) if (!evaluation) throw new Error(`Evaluation ${id} not found`) const additionalConfig = evaluation.additionalConfig ? JSON.parse(evaluation.additionalConfig) : {} @@ -55,13 +56,13 @@ const runAgain = async (id: string, baseURL: string, orgId: string) => { } } data.version = true - return await createEvaluation(data, baseURL, orgId) + return await createEvaluation(data, baseURL, orgId, workspaceId) } catch (error) { throw new InternalFlowiseError(StatusCodes.INTERNAL_SERVER_ERROR, `Error: EvalsService.runAgain - ${getErrorMessage(error)}`) } } -const createEvaluation = async (body: ICommonObject, baseURL: string, orgId: string) => { +const createEvaluation = async (body: ICommonObject, baseURL: string, orgId: string, workspaceId: string) => { try { const appServer = getRunningExpressApp() const newEval = new Evaluation() @@ -97,7 +98,8 @@ const createEvaluation = async (body: ICommonObject, baseURL: string, orgId: str ) const dataset = await appServer.AppDataSource.getRepository(Dataset).findOneBy({ - id: body.datasetId + id: body.datasetId, + workspaceId: workspaceId }) if (!dataset) throw new Error(`Dataset ${body.datasetId} not found`) @@ -124,7 +126,8 @@ const createEvaluation = async (body: ICommonObject, baseURL: string, orgId: str for (let i = 0; i < chatflowIds.length; i++) { const chatflowId = chatflowIds[i] const cFlow = await appServer.AppDataSource.getRepository(ChatFlow).findOneBy({ - id: chatflowId + id: chatflowId, + workspaceId: workspaceId }) if (cFlow && cFlow.apikeyid) { const apikeyObj = await appServer.AppDataSource.getRepository(ApiKey).findOneBy({ @@ -338,7 +341,7 @@ const createEvaluation = async (body: ICommonObject, baseURL: string, orgId: str } } -const getAllEvaluations = async (workspaceId?: string, page: number = -1, limit: number = -1) => { +const getAllEvaluations = async (workspaceId: string, page: number = -1, limit: number = -1) => { try { const appServer = getRunningExpressApp() @@ -421,7 +424,7 @@ const getAllEvaluations = async (workspaceId?: string, page: number = -1, limit: } // Delete evaluation and all rows via id -const deleteEvaluation = async (id: string, activeWorkspaceId?: string) => { +const deleteEvaluation = async (id: string, activeWorkspaceId: string) => { try { const appServer = getRunningExpressApp() await appServer.AppDataSource.getRepository(Evaluation).delete({ id: id }) @@ -437,11 +440,12 @@ const deleteEvaluation = async (id: string, activeWorkspaceId?: string) => { } // check for outdated evaluations -const isOutdated = async (id: string) => { +const isOutdated = async (id: string, workspaceId: string) => { try { const appServer = getRunningExpressApp() const evaluation = await appServer.AppDataSource.getRepository(Evaluation).findOneBy({ - id: id + id: id, + workspaceId: workspaceId }) if (!evaluation) throw new Error(`Evaluation ${id} not found`) const evaluationRunDate = evaluation.runDate.getTime() @@ -456,7 +460,8 @@ const isOutdated = async (id: string) => { // check if the evaluation is outdated by extracting the runTime and then check with the dataset last updated time as well // as the chatflows last updated time. If the evaluation is outdated, then return true else return false const dataset = await appServer.AppDataSource.getRepository(Dataset).findOneBy({ - id: evaluation.datasetId + id: evaluation.datasetId, + workspaceId: workspaceId }) if (dataset) { const datasetLastUpdated = dataset.updatedDate.getTime() @@ -483,7 +488,8 @@ const isOutdated = async (id: string) => { } } const chatflow = await appServer.AppDataSource.getRepository(ChatFlow).findOneBy({ - id: chatflowIds[i] + id: chatflowIds[i], + workspaceId: workspaceId }) if (!chatflow) { returnObj.errors.push({ @@ -511,7 +517,8 @@ const isOutdated = async (id: string) => { continue } const assistant = await appServer.AppDataSource.getRepository(Assistant).findOneBy({ - id: chatflowIds[i] + id: chatflowIds[i], + workspaceId: workspaceId }) if (!assistant) { returnObj.errors.push({ @@ -540,11 +547,12 @@ const isOutdated = async (id: string) => { } } -const getEvaluation = async (id: string) => { +const getEvaluation = async (id: string, workspaceId: string) => { try { const appServer = getRunningExpressApp() const evaluation = await appServer.AppDataSource.getRepository(Evaluation).findOneBy({ - id: id + id: id, + workspaceId: workspaceId }) if (!evaluation) throw new Error(`Evaluation ${id} not found`) const versionCount = await appServer.AppDataSource.getRepository(Evaluation).countBy({ @@ -553,7 +561,7 @@ const getEvaluation = async (id: string) => { const items = await appServer.AppDataSource.getRepository(EvaluationRun).find({ where: { evaluationId: id } }) - const versions = (await getVersions(id)).versions + const versions = (await getVersions(id, workspaceId)).versions const versionNo = versions.findIndex((version) => version.id === id) + 1 return { ...evaluation, @@ -566,11 +574,12 @@ const getEvaluation = async (id: string) => { } } -const getVersions = async (id: string) => { +const getVersions = async (id: string, workspaceId: string) => { try { const appServer = getRunningExpressApp() const evaluation = await appServer.AppDataSource.getRepository(Evaluation).findOneBy({ - id: id + id: id, + workspaceId: workspaceId }) if (!evaluation) throw new Error(`Evaluation ${id} not found`) const versions = await appServer.AppDataSource.getRepository(Evaluation).find({ @@ -597,12 +606,13 @@ const getVersions = async (id: string) => { } } -const patchDeleteEvaluations = async (ids: string[] = [], isDeleteAllVersion?: boolean, activeWorkspaceId?: string) => { +const patchDeleteEvaluations = async (ids: string[] = [], activeWorkspaceId: string, isDeleteAllVersion?: boolean) => { try { const appServer = getRunningExpressApp() const evalsToBeDeleted = await appServer.AppDataSource.getRepository(Evaluation).find({ where: { - id: In(ids) + id: In(ids), + workspaceId: activeWorkspaceId } }) await appServer.AppDataSource.getRepository(Evaluation).delete(ids) diff --git a/packages/server/src/services/evaluator/index.ts b/packages/server/src/services/evaluator/index.ts index 3cfbcc6f399..bd3d7e23a30 100644 --- a/packages/server/src/services/evaluator/index.ts +++ b/packages/server/src/services/evaluator/index.ts @@ -5,11 +5,11 @@ import { getErrorMessage } from '../../errors/utils' import { Evaluator } from '../../database/entities/Evaluator' import { EvaluatorDTO } from '../../Interface.Evaluation' -const getAllEvaluators = async (workspaceId?: string, page: number = -1, limit: number = -1) => { +const getAllEvaluators = async (workspaceId: string, page: number = -1, limit: number = -1) => { try { const appServer = getRunningExpressApp() const queryBuilder = appServer.AppDataSource.getRepository(Evaluator).createQueryBuilder('ev').orderBy('ev.updatedDate', 'DESC') - if (workspaceId) queryBuilder.andWhere('ev.workspaceId = :workspaceId', { workspaceId }) + queryBuilder.andWhere('ev.workspaceId = :workspaceId', { workspaceId }) if (page > 0 && limit > 0) { queryBuilder.skip((page - 1) * limit) queryBuilder.take(limit) @@ -31,11 +31,12 @@ const getAllEvaluators = async (workspaceId?: string, page: number = -1, limit: } } -const getEvaluator = async (id: string) => { +const getEvaluator = async (id: string, workspaceId: string) => { try { const appServer = getRunningExpressApp() const evaluator = await appServer.AppDataSource.getRepository(Evaluator).findOneBy({ - id: id + id: id, + workspaceId: workspaceId }) if (!evaluator) throw new Error(`Evaluator ${id} not found`) return EvaluatorDTO.fromEntity(evaluator) @@ -65,11 +66,12 @@ const createEvaluator = async (body: any) => { } // Update Evaluator -const updateEvaluator = async (id: string, body: any) => { +const updateEvaluator = async (id: string, body: any, workspaceId: string) => { try { const appServer = getRunningExpressApp() const evaluator = await appServer.AppDataSource.getRepository(Evaluator).findOneBy({ - id: id + id: id, + workspaceId: workspaceId }) if (!evaluator) throw new Error(`Evaluator ${id} not found`) @@ -88,10 +90,10 @@ const updateEvaluator = async (id: string, body: any) => { } // Delete Evaluator via id -const deleteEvaluator = async (id: string) => { +const deleteEvaluator = async (id: string, workspaceId: string) => { try { const appServer = getRunningExpressApp() - return await appServer.AppDataSource.getRepository(Evaluator).delete({ id: id }) + return await appServer.AppDataSource.getRepository(Evaluator).delete({ id: id, workspaceId: workspaceId }) } catch (error) { throw new InternalFlowiseError( StatusCodes.INTERNAL_SERVER_ERROR, diff --git a/packages/server/src/services/variables/index.ts b/packages/server/src/services/variables/index.ts index fb1f10a48ae..5b427e95488 100644 --- a/packages/server/src/services/variables/index.ts +++ b/packages/server/src/services/variables/index.ts @@ -32,10 +32,10 @@ const createVariable = async (newVariable: Variable, orgId: string) => { } } -const deleteVariable = async (variableId: string): Promise => { +const deleteVariable = async (variableId: string, workspaceId: string): Promise => { try { const appServer = getRunningExpressApp() - const dbResponse = await appServer.AppDataSource.getRepository(Variable).delete({ id: variableId }) + const dbResponse = await appServer.AppDataSource.getRepository(Variable).delete({ id: variableId, workspaceId: workspaceId }) return dbResponse } catch (error) { throw new InternalFlowiseError( @@ -45,7 +45,7 @@ const deleteVariable = async (variableId: string): Promise => { } } -const getAllVariables = async (workspaceId?: string, page: number = -1, limit: number = -1) => { +const getAllVariables = async (workspaceId: string, page: number = -1, limit: number = -1) => { try { const appServer = getRunningExpressApp() const queryBuilder = appServer.AppDataSource.getRepository(Variable) @@ -77,11 +77,12 @@ const getAllVariables = async (workspaceId?: string, page: number = -1, limit: n } } -const getVariableById = async (variableId: string) => { +const getVariableById = async (variableId: string, workspaceId: string) => { try { const appServer = getRunningExpressApp() const dbResponse = await appServer.AppDataSource.getRepository(Variable).findOneBy({ - id: variableId + id: variableId, + workspaceId: workspaceId }) if (appServer.identityManager.getPlatformType() === Platform.CLOUD && dbResponse?.type === 'runtime') { From 22b36684e141a89d3cdf07ee63cc4fae9fde7142 Mon Sep 17 00:00:00 2001 From: Vinod Kiran Date: Wed, 30 Jul 2025 15:34:26 +0530 Subject: [PATCH 4/7] Update EvaluatorRunner and index to require workspaceId for evaluator retrieval - Modified the runAdditionalEvaluators function to accept workspaceId as a parameter. --- packages/server/src/services/evaluations/EvaluatorRunner.ts | 5 +++-- packages/server/src/services/evaluations/index.ts | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/server/src/services/evaluations/EvaluatorRunner.ts b/packages/server/src/services/evaluations/EvaluatorRunner.ts index 4b2d7d81da1..3f2a42081d7 100644 --- a/packages/server/src/services/evaluations/EvaluatorRunner.ts +++ b/packages/server/src/services/evaluations/EvaluatorRunner.ts @@ -14,7 +14,8 @@ export const runAdditionalEvaluators = async ( metricsArray: ICommonObject[], actualOutputArray: string[], errorArray: string[], - selectedEvaluators: string[] + selectedEvaluators: string[], + workspaceId: string ) => { const evaluationResults: any[] = [] const evaluatorDict: any = {} @@ -27,7 +28,7 @@ export const runAdditionalEvaluators = async ( const evaluatorId = selectedEvaluators[i] let evaluator = evaluatorDict[evaluatorId] if (!evaluator) { - evaluator = await evaluatorsService.getEvaluator(evaluatorId) + evaluator = await evaluatorsService.getEvaluator(evaluatorId, workspaceId) evaluatorDict[evaluatorId] = evaluator } diff --git a/packages/server/src/services/evaluations/index.ts b/packages/server/src/services/evaluations/index.ts index 3d1b13d4c9e..fe0aae71b73 100644 --- a/packages/server/src/services/evaluations/index.ts +++ b/packages/server/src/services/evaluations/index.ts @@ -246,7 +246,8 @@ const createEvaluation = async (body: ICommonObject, baseURL: string, orgId: str metricsArray, actualOutputArray, errorArray, - body.selectedSimpleEvaluators.length > 0 ? JSON.parse(body.selectedSimpleEvaluators) : [] + body.selectedSimpleEvaluators.length > 0 ? JSON.parse(body.selectedSimpleEvaluators) : [], + workspaceId ) newRun.evaluators = JSON.stringify(results) @@ -260,7 +261,7 @@ const createEvaluation = async (body: ICommonObject, baseURL: string, orgId: str const llmEvaluatorMap: { evaluatorId: string; evaluator: any }[] = [] for (let i = 0; i < resultRow.LLMEvaluators.length; i++) { const evaluatorId = resultRow.LLMEvaluators[i] - const evaluator = await evaluatorsService.getEvaluator(evaluatorId) + const evaluator = await evaluatorsService.getEvaluator(evaluatorId, workspaceId) llmEvaluatorMap.push({ evaluatorId: evaluatorId, evaluator: evaluator From 4b3ab55c9c00ba322d11b0d32ac2dd9bfd7370d9 Mon Sep 17 00:00:00 2001 From: Vinod Kiran Date: Wed, 30 Jul 2025 15:42:27 +0530 Subject: [PATCH 5/7] lint fixes --- packages/server/src/controllers/apikey/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/server/src/controllers/apikey/index.ts b/packages/server/src/controllers/apikey/index.ts index a13f02f7f20..677d689311c 100644 --- a/packages/server/src/controllers/apikey/index.ts +++ b/packages/server/src/controllers/apikey/index.ts @@ -42,7 +42,7 @@ const updateApiKey = async (req: Request, res: Response, next: NextFunction) => } if (typeof req.body === 'undefined' || !req.body.keyName) { throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Error: apikeyController.updateApiKey - keyName not provided!`) - } + } if (!req.user?.activeWorkspaceId) { throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Workspace ID is required`) } From a8cc737d667035cedf7ca899a5ac3fd533f39a38 Mon Sep 17 00:00:00 2001 From: Vinod Paidimarry Date: Mon, 4 Aug 2025 22:12:47 +0530 Subject: [PATCH 6/7] Enhancement/Integrate workspaceId in chatflow and flow-config services - Updated chatflow and flow-config controllers to require workspaceId for fetching chatflows. - Modified service methods to accept workspaceId as a parameter, ensuring proper context for chatflow retrieval. --- .../src/controllers/chat-messages/index.ts | 2 +- .../server/src/controllers/chatflows/index.ts | 25 ++++++++++++------- .../src/controllers/flow-configs/index.ts | 9 ++++++- .../src/controllers/marketplaces/index.ts | 6 +++++ .../src/controllers/predictions/index.ts | 4 ++- .../server/src/services/chatflows/index.ts | 9 ++++--- .../server/src/services/flow-configs/index.ts | 4 +-- .../server/src/services/marketplaces/index.ts | 2 +- packages/server/src/utils/index.ts | 2 +- 9 files changed, 44 insertions(+), 19 deletions(-) diff --git a/packages/server/src/controllers/chat-messages/index.ts b/packages/server/src/controllers/chat-messages/index.ts index b000c9ea3fb..d1d7cccbab7 100644 --- a/packages/server/src/controllers/chat-messages/index.ts +++ b/packages/server/src/controllers/chat-messages/index.ts @@ -166,7 +166,7 @@ const removeAllChatMessages = async (req: Request, res: Response, next: NextFunc ) } const chatflowid = req.params.id - const chatflow = await chatflowsService.getChatflowById(req.params.id) + const chatflow = await chatflowsService.getChatflowById(req.params.id, workspaceId) if (!chatflow) { return res.status(404).send(`Chatflow ${req.params.id} not found`) } diff --git a/packages/server/src/controllers/chatflows/index.ts b/packages/server/src/controllers/chatflows/index.ts index 000a2770a42..a7ee59703f3 100644 --- a/packages/server/src/controllers/chatflows/index.ts +++ b/packages/server/src/controllers/chatflows/index.ts @@ -107,7 +107,14 @@ const getChatflowById = async (req: Request, res: Response, next: NextFunction) if (typeof req.params === 'undefined' || !req.params.id) { throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Error: chatflowsController.getChatflowById - id not provided!`) } - const apiResponse = await chatflowsService.getChatflowById(req.params.id) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: chatflowsController.getChatflowById - workspace ${workspaceId} not found!` + ) + } + const apiResponse = await chatflowsService.getChatflowById(req.params.id, workspaceId) return res.json(apiResponse) } catch (error) { next(error) @@ -162,7 +169,14 @@ const updateChatflow = async (req: Request, res: Response, next: NextFunction) = if (typeof req.params === 'undefined' || !req.params.id) { throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Error: chatflowsController.updateChatflow - id not provided!`) } - const chatflow = await chatflowsService.getChatflowById(req.params.id) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: chatflowsController.saveChatflow - workspace ${workspaceId} not found!` + ) + } + const chatflow = await chatflowsService.getChatflowById(req.params.id, workspaceId) if (!chatflow) { return res.status(404).send(`Chatflow ${req.params.id} not found`) } @@ -173,13 +187,6 @@ const updateChatflow = async (req: Request, res: Response, next: NextFunction) = `Error: chatflowsController.saveChatflow - organization ${orgId} not found!` ) } - const workspaceId = req.user?.activeWorkspaceId - if (!workspaceId) { - throw new InternalFlowiseError( - StatusCodes.NOT_FOUND, - `Error: chatflowsController.saveChatflow - workspace ${workspaceId} not found!` - ) - } const subscriptionId = req.user?.activeOrganizationSubscriptionId || '' const body = req.body const updateChatFlow = new ChatFlow() diff --git a/packages/server/src/controllers/flow-configs/index.ts b/packages/server/src/controllers/flow-configs/index.ts index c0926266085..ba5fadeee38 100644 --- a/packages/server/src/controllers/flow-configs/index.ts +++ b/packages/server/src/controllers/flow-configs/index.ts @@ -11,7 +11,14 @@ const getSingleFlowConfig = async (req: Request, res: Response, next: NextFuncti `Error: flowConfigsController.getSingleFlowConfig - id not provided!` ) } - const apiResponse = await flowConfigsService.getSingleFlowConfig(req.params.id) + const workspaceId = req.user?.activeWorkspaceId + if (!workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: flowConfigsController.getSingleFlowConfig - workspace ${workspaceId} not found!` + ) + } + const apiResponse = await flowConfigsService.getSingleFlowConfig(req.params.id, workspaceId) return res.json(apiResponse) } catch (error) { next(error) diff --git a/packages/server/src/controllers/marketplaces/index.ts b/packages/server/src/controllers/marketplaces/index.ts index 5d19d40e6cd..1984f3ad938 100644 --- a/packages/server/src/controllers/marketplaces/index.ts +++ b/packages/server/src/controllers/marketplaces/index.ts @@ -47,6 +47,12 @@ const saveCustomTemplate = async (req: Request, res: Response, next: NextFunctio } const body = req.body body.workspaceId = req.user?.activeWorkspaceId + if (!body.workspaceId) { + throw new InternalFlowiseError( + StatusCodes.NOT_FOUND, + `Error: marketplacesController.saveCustomTemplate - workspace ${body.workspaceId} not found!` + ) + } const apiResponse = await marketplacesService.saveCustomTemplate(body) return res.json(apiResponse) } catch (error) { diff --git a/packages/server/src/controllers/predictions/index.ts b/packages/server/src/controllers/predictions/index.ts index b7f79b642c8..eef1186c382 100644 --- a/packages/server/src/controllers/predictions/index.ts +++ b/packages/server/src/controllers/predictions/index.ts @@ -25,7 +25,9 @@ const createPrediction = async (req: Request, res: Response, next: NextFunction) `Error: predictionsController.createPrediction - body not provided!` ) } - const chatflow = await chatflowsService.getChatflowById(req.params.id) + const workspaceId = req.user?.activeWorkspaceId + + const chatflow = await chatflowsService.getChatflowById(req.params.id, workspaceId) if (!chatflow) { throw new InternalFlowiseError(StatusCodes.NOT_FOUND, `Chatflow ${req.params.id} not found`) } diff --git a/packages/server/src/services/chatflows/index.ts b/packages/server/src/services/chatflows/index.ts index 9ce0a529b03..b3dfa7b28fe 100644 --- a/packages/server/src/services/chatflows/index.ts +++ b/packages/server/src/services/chatflows/index.ts @@ -229,11 +229,14 @@ const getChatflowByApiKey = async (apiKeyId: string, keyonly?: unknown): Promise } } -const getChatflowById = async (chatflowId: string): Promise => { +const getChatflowById = async (chatflowId: string, workspaceId?: string): Promise => { try { const appServer = getRunningExpressApp() - const dbResponse = await appServer.AppDataSource.getRepository(ChatFlow).findOneBy({ - id: chatflowId + const dbResponse = await appServer.AppDataSource.getRepository(ChatFlow).findOne({ + where: { + id: chatflowId, + ...(workspaceId ? { workspaceId } : {}) + } }) if (!dbResponse) { throw new InternalFlowiseError(StatusCodes.NOT_FOUND, `Chatflow ${chatflowId} not found in the database!`) diff --git a/packages/server/src/services/flow-configs/index.ts b/packages/server/src/services/flow-configs/index.ts index 8ce05499f2c..7755e86f39e 100644 --- a/packages/server/src/services/flow-configs/index.ts +++ b/packages/server/src/services/flow-configs/index.ts @@ -6,10 +6,10 @@ import chatflowsService from '../chatflows' import { InternalFlowiseError } from '../../errors/internalFlowiseError' import { getErrorMessage } from '../../errors/utils' -const getSingleFlowConfig = async (chatflowId: string): Promise => { +const getSingleFlowConfig = async (chatflowId: string, workspaceId: string): Promise => { try { const appServer = getRunningExpressApp() - const chatflow = await chatflowsService.getChatflowById(chatflowId) + const chatflow = await chatflowsService.getChatflowById(chatflowId, workspaceId) if (!chatflow) { throw new InternalFlowiseError(StatusCodes.NOT_FOUND, `Chatflow ${chatflowId} not found in the database!`) } diff --git a/packages/server/src/services/marketplaces/index.ts b/packages/server/src/services/marketplaces/index.ts index 6f7f9c6b654..c7a3b26a18c 100644 --- a/packages/server/src/services/marketplaces/index.ts +++ b/packages/server/src/services/marketplaces/index.ts @@ -211,7 +211,7 @@ const saveCustomTemplate = async (body: any): Promise => { Object.assign(customTemplate, body) if (body.chatflowId) { - const chatflow = await chatflowsService.getChatflowById(body.chatflowId) + const chatflow = await chatflowsService.getChatflowById(body.chatflowId, body.workspaceId) const flowData = JSON.parse(chatflow.flowData) const { framework, exportJson } = _generateExportFlowData(flowData) flowDataStr = JSON.stringify(exportJson) diff --git a/packages/server/src/utils/index.ts b/packages/server/src/utils/index.ts index 7d76471a3b0..8b834e7b62e 100644 --- a/packages/server/src/utils/index.ts +++ b/packages/server/src/utils/index.ts @@ -834,7 +834,7 @@ export const getGlobalVariable = async ( id: '', updatedDate: new Date(), createdDate: new Date(), - workspaceId: 'dummy' + workspaceId: '' }) } } From fe4e59ad8b8c1e43b64990fc5ef38f1f3acd78c1 Mon Sep 17 00:00:00 2001 From: Henry Date: Mon, 18 Aug 2025 19:46:35 +0800 Subject: [PATCH 7/7] lint fix --- packages/server/src/controllers/predictions/index.ts | 2 +- packages/server/src/services/documentstore/index.ts | 8 +------- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/packages/server/src/controllers/predictions/index.ts b/packages/server/src/controllers/predictions/index.ts index eef1186c382..d467f3157e4 100644 --- a/packages/server/src/controllers/predictions/index.ts +++ b/packages/server/src/controllers/predictions/index.ts @@ -26,7 +26,7 @@ const createPrediction = async (req: Request, res: Response, next: NextFunction) ) } const workspaceId = req.user?.activeWorkspaceId - + const chatflow = await chatflowsService.getChatflowById(req.params.id, workspaceId) if (!chatflow) { throw new InternalFlowiseError(StatusCodes.NOT_FOUND, `Chatflow ${req.params.id} not found`) diff --git a/packages/server/src/services/documentstore/index.ts b/packages/server/src/services/documentstore/index.ts index 6c9171ffc4a..0ee1cad2015 100644 --- a/packages/server/src/services/documentstore/index.ts +++ b/packages/server/src/services/documentstore/index.ts @@ -311,13 +311,7 @@ const getDocumentStoreFileChunks = async ( } } -const deleteDocumentStore = async ( - storeId: string, - orgId: string, - workspaceId: string, - usageCacheManager: UsageCacheManager, - isDeleteBoth: boolean = false -) => { +const deleteDocumentStore = async (storeId: string, orgId: string, workspaceId: string, usageCacheManager: UsageCacheManager) => { try { const appServer = getRunningExpressApp()