Атрибуция от бота в MCP/REST + REST API по ключу (этап 2)

- MCP: getActor (владелец ключа + бот), аудит changedByName=бот/label ключа, botId, metadata.source='mcp'; аудит для update_task/update_task_status
- sendTaskMessage: botId (messageType 'bot'), починен путь isBotToken без req.user
- authenticateTokenOrApiKey: JWT или X-Api-Key с белым списком endpoint'ов (/api/upload, messages, field-values, create task), проверки скоупов, аудит source='api'
- Лимиты файлов через env: UPLOAD_IMAGE_MAX_MB=25, UPLOAD_DOC_MAX_MB=100, UPLOAD_MAX_MB=100
- MCP upload-инструменты: параметр fileUrl для привязки уже загруженного файла; новый инструмент get_api_guide
This commit is contained in:
2026-07-22 15:18:04 +03:00
parent 68153caef2
commit 8cfd49fd9f
13 changed files with 720 additions and 246 deletions

View File

@@ -31,6 +31,7 @@ export interface UploadFileFromBase64Params {
mimeType?: string;
taskId?: number | null; // опциональная привязка к задаче
fieldId?: number | null; // опциональная привязка к полю формы
botId?: number | null; // атрибуция загрузки ботом (file_uploads.bot_id)
}
export interface UploadedFileInfo {
@@ -50,7 +51,7 @@ const MAX_BASE64_LENGTH = Math.ceil(DOC_MAX_SIZE * 4 / 3) + 1024;
// whitelist расширений, magic bytes, раздельные лимиты (10 МБ изображения / 50 МБ прочее).
// Создаёт запись трекинга в file_uploads.
export async function uploadFileFromBase64(params: UploadFileFromBase64Params): Promise<UploadedFileInfo> {
const { organizationId, userId, taskId = null, fieldId = null } = params;
const { organizationId, userId, taskId = null, fieldId = null, botId = null } = params;
// 1. Имя файла: whitelist расширений + запрет недопустимых символов (как в multer fileFilter)
const name = path.basename(params.fileName || '');
@@ -123,6 +124,7 @@ export async function uploadFileFromBase64(params: UploadFileFromBase64Params):
sizeBytes: buffer.length,
taskId,
fieldId,
botId,
}).returning({ id: fileUploads.id });
fileUploadId = row?.id ?? null;
} catch (trackErr) {