import crypto from 'crypto'; // ── Presigned-токены для временного доступа к файлам без авторизации ───────── // Вынесено из index.ts: используется и файловыми маршрутами (/api/files/:key/presigned), // и MCP get_task_file — последний отдаёт внешний прокси-URL приложения // (/api/files/?presigned=) вместо внутреннего хоста MinIO // (http://minio:9000/...), который снаружи docker-сети недоступен. // Токены in-memory: при multi-instance понадобится Redis (как upload-тикеты). interface PresignedToken { fileKey: string; organizationId: number; expiresAt: number; } const presignedTokens = new Map(); export const PRESIGNED_TTL_MS = 5 * 60 * 1000; // 5 minutes export function generatePresignedToken(fileKey: string, organizationId: number): string { const token = crypto.randomBytes(32).toString('hex'); presignedTokens.set(token, { fileKey, organizationId, expiresAt: Date.now() + PRESIGNED_TTL_MS }); return token; } export function validatePresignedToken(token: string, fileKey: string): number | null { const entry = presignedTokens.get(token); if (!entry) return null; if (entry.fileKey !== fileKey) return null; if (entry.expiresAt <= Date.now()) { presignedTokens.delete(token); return null; } return entry.organizationId; } export function sweepPresignedTokens(): void { const now = Date.now(); for (const [token, entry] of presignedTokens.entries()) { if (entry.expiresAt <= now) { presignedTokens.delete(token); } } }