/** * File Organizer MCP Server v3.4.2 * Categorizer Service */ import type { FileWithSize, CategoryStats, CategoryName, CustomRule, AudioMetadata, ImageMetadata } from "../types.js"; import { ContentAnalyzerService } from "./content-analyzer.service.js"; import { MetadataCacheService } from "./metadata-cache.service.js"; /** * Categorizer Service - file categorization by type * Now with content-based detection for enhanced security */ export declare class CategorizerService { private contentAnalyzer?; private metadataCache?; private customRules; private pathValidator; private contentAnalysisPromises; private contentAnalysisResults; private contentAnalysisTimestamps; private static readonly CONTENT_ANALYSIS_TTL_MS; private static readonly CONTENT_ANALYSIS_CLEANUP_INTERVAL_MS; private cleanupInterval; private regexCache; private getCachedRegex; constructor(contentAnalyzer?: ContentAnalyzerService | undefined, metadataCache?: MetadataCacheService | undefined); /** * Start periodic cleanup interval for stale content analysis entries */ private startCleanupInterval; /** * Clean up stale entries from content analysis Maps */ private cleanupStaleContentAnalysis; /** * Stop cleanup interval (for testing) */ stopCleanupInterval(): void; /** * Clean up resources - stops the cleanup interval */ destroy(): void; /** * Set custom categorization rules * @returns Number of valid rules applied */ setCustomRules(rules: CustomRule[]): number; /** * Get real extension from files with double extensions * Note: timeout parameter is not currently implemented - regex execution is synchronous */ private getRealExtension; /** * Validate regex pattern for security (prevent ReDoS) */ validateRegexPattern(pattern: string, category: string): void; /** * Safe regex test with ReDoS protection * Note: timeout parameter is not currently implemented - uses string length limiting instead */ private safeRegexTest; /** * Get real extension from files with double extensions */ /** * Validate category name for security */ validateCategoryName(name: string): void; /** * Get category for a file * @param name - File name * @param useContentAnalysis - When true, verify extension matches content asynchronously * @param filePath - Optional file path for content analysis (required if useContentAnalysis is true) * @returns Category name */ getCategory(name: string, useContentAnalysis?: boolean, filePath?: string): CategoryName; /** * Trigger async content analysis in the background * @param name - File name (used as key for result retrieval) * @param filePath - Full file path for analysis */ private triggerContentAnalysis; /** * Get the updated category from background content analysis (if available) * @param name - File name * @param filePath - Full file path * @returns Updated category or undefined if analysis not yet complete */ getUpdatedCategory(name: string, filePath: string): CategoryName | undefined; /** * Wait for content analysis to complete and get the final category * @param name - File name * @param filePath - Full file path * @returns Category after content analysis completes */ waitForContentAnalysis(name: string, filePath: string): Promise; /** * Clear content analysis cache for a specific file * @param filePath - File path to clear */ clearContentAnalysisCache(filePath?: string): void; /** * Get category by extension only (original logic) */ private getCategoryByExtension; /** * Get category using content analysis (more secure than extension-only) * Falls back to extension-based if content analysis fails */ getCategoryByContent(filePath: string): Promise<{ category: CategoryName; confidence: number; warnings: string[]; metadata?: AudioMetadata | ImageMetadata; }>; /** * Get category with metadata for enhanced security detection */ getCategoryWithMetadata(filePath: string): Promise<{ category: CategoryName; confidence: number; warnings: string[]; metadata?: AudioMetadata | ImageMetadata; }>; /** * Check if file should be in quarantine based on metadata + security */ isQuarantined(filePath: string): Promise; /** * Get enhanced security classification with metadata context */ getSecurityClassificationWithMetadata(filePath: string): Promise<{ isExecutable: boolean; isSuspicious: boolean; threatLevel: "none" | "low" | "medium" | "high"; reason?: string; metadata?: AudioMetadata | ImageMetadata; }>; /** * Check if file extension matches actual content */ validateFileType(filePath: string): Promise<{ valid: boolean; declaredExtension: string; actualType: string; mismatch: boolean; }>; /** * Get security classification for a file */ classifySecurity(filePath: string): Promise<{ isExecutable: boolean; isSuspicious: boolean; threatLevel: "none" | "low" | "medium" | "high"; reason?: string; }>; /** * Map content-detected type to file organizer category */ private mapContentTypeToCategory; /** * Check if detected type is an executable disguised as document */ private isExecutableDisguisedAsDocument; /** * Check if type represents executable content */ private isExecutableType; /** * Check if extension is executable */ private isExecutableExtension; /** * Check for double extension patterns (e.g., file.jpg.exe) */ private hasDoubleExtension; /** * Get the real executable extension from files with double extensions * For example, returns '.exe' for 'file.jpg.exe' */ /** * Categorize files by their type */ categorizeFiles(files: FileWithSize[]): Partial>; } //# sourceMappingURL=categorizer.service.d.ts.map