Browse Source

Merge pull request #10806 from growilabs/fix/openai-thread-idor

fix: Openai thread IDOR
mergify[bot] 1 month ago
parent
commit
b91bd9b797

+ 9 - 0
apps/app/src/features/openai/server/routes/delete-thread.ts

@@ -14,6 +14,7 @@ import type { ApiV3Response } from '~/server/routes/apiv3/interfaces/apiv3-respo
 import loggerFactory from '~/utils/logger';
 
 import type { IApiv3DeleteThreadParams } from '../../interfaces/thread-relation';
+import ThreadRelationModel from '../models/thread-relation';
 import { getOpenaiService } from '../services/openai';
 import { certifyAiService } from './middlewares/certify-ai-service';
 
@@ -68,6 +69,14 @@ export const deleteThreadFactory = (crowi: Crowi): RequestHandler[] => {
       }
 
       try {
+        const threadRelation = await ThreadRelationModel.findOne({
+          _id: threadRelationId,
+          userId: user._id,
+        });
+        if (threadRelation == null) {
+          return res.apiv3Err(new ErrorV3('Thread not found'), 404);
+        }
+
         const deletedThreadRelation =
           await openaiService.deleteThread(threadRelationId);
         return res.apiv3({ deletedThreadRelation });

+ 1 - 0
apps/app/src/features/openai/server/routes/edit/index.ts

@@ -246,6 +246,7 @@ export const postMessageToEditHandlersFactory = (
 
       const threadRelation = await ThreadRelationModel.findOne({
         threadId: { $eq: threadId },
+        userId: user._id,
       });
       if (threadRelation == null) {
         return res.apiv3Err(new ErrorV3('ThreadRelation not found'), 404);

+ 4 - 2
apps/app/src/features/openai/server/routes/get-threads.ts

@@ -70,8 +70,10 @@ export const getThreadsFactory = (crowi: Crowi): RequestHandler[] => {
           );
         }
 
-        const threads =
-          await openaiService.getThreadsByAiAssistantId(aiAssistantId);
+        const threads = await openaiService.getThreadsByAiAssistantId(
+          aiAssistantId,
+          user._id,
+        );
 
         return res.apiv3({ threads });
       } catch (err) {

+ 9 - 0
apps/app/src/features/openai/server/routes/message/get-messages.ts

@@ -12,6 +12,7 @@ import loginRequiredFactory from '~/server/middlewares/login-required';
 import type { ApiV3Response } from '~/server/routes/apiv3/interfaces/apiv3-response';
 import loggerFactory from '~/utils/logger';
 
+import ThreadRelationModel from '../../models/thread-relation';
 import { getOpenaiService } from '../../services/openai';
 import { certifyAiService } from '../middlewares/certify-ai-service';
 
@@ -81,6 +82,14 @@ export const getMessagesFactory = (crowi: Crowi): RequestHandler[] => {
           );
         }
 
+        const threadRelation = await ThreadRelationModel.findOne({
+          threadId: { $eq: threadId },
+          userId: user._id,
+        });
+        if (threadRelation == null) {
+          return res.apiv3Err(new ErrorV3('Thread not found'), 404);
+        }
+
         const messages = await openaiService.getMessageData(
           threadId,
           user.lang,

+ 4 - 1
apps/app/src/features/openai/server/routes/message/post-message.ts

@@ -128,7 +128,10 @@ export const postMessageHandlersFactory = (crowi: Crowi): RequestHandler[] => {
         return res.apiv3Err(new ErrorV3('AI assistant not found'), 404);
       }
 
-      const threadRelation = await ThreadRelationModel.findOne({ threadId });
+      const threadRelation = await ThreadRelationModel.findOne({
+        threadId: { $eq: threadId },
+        userId: user._id,
+      });
       if (threadRelation == null) {
         return res.apiv3Err(new ErrorV3('ThreadRelation not found'), 404);
       }

+ 12 - 2
apps/app/src/features/openai/server/services/openai.ts

@@ -98,6 +98,7 @@ export interface IOpenaiService {
   ): Promise<ThreadRelationDocument>;
   getThreadsByAiAssistantId(
     aiAssistantId: string,
+    userId?: string,
   ): Promise<ThreadRelationDocument[]>;
   deleteThread(threadRelationId: string): Promise<ThreadRelationDocument>;
   deleteExpiredThreads(limit: number, apiCallInterval: number): Promise<void>; // for CronJob
@@ -290,12 +291,21 @@ class OpenaiService implements IOpenaiService {
 
   async getThreadsByAiAssistantId(
     aiAssistantId: string,
+    userId?: string,
     type: ThreadType = ThreadType.KNOWLEDGE,
   ): Promise<ThreadRelationDocument[]> {
-    const threadRelations = await ThreadRelationModel.find({
+    const query: { aiAssistant: string; type: ThreadType; userId?: string } = {
       aiAssistant: aiAssistantId,
       type,
-    }).sort({ updatedAt: -1 });
+    };
+
+    if (userId != null) {
+      query.userId = userId;
+    }
+
+    const threadRelations = await ThreadRelationModel.find(query).sort({
+      updatedAt: -1,
+    });
     return threadRelations;
   }