UNPKG

msexchange-mcp

Version:

MCP server for Microsoft Exchange/Outlook email operations via Microsoft Graph API

180 lines 5.13 kB
/** * Input validation utilities */ /** * Validate date range */ export function validateDateRange(start, end) { if (!start && !end) { return { valid: true }; } let startDate; let endDate; // Parse start date if (start) { startDate = typeof start === 'string' ? new Date(start) : start; if (isNaN(startDate.getTime())) { return { valid: false, error: 'Invalid start date format. Use YYYY-MM-DD' }; } } // Parse end date if (end) { endDate = typeof end === 'string' ? new Date(end) : end; if (isNaN(endDate.getTime())) { return { valid: false, error: 'Invalid end date format. Use YYYY-MM-DD' }; } } // Check if start is before end if (startDate && endDate && startDate > endDate) { return { valid: false, error: 'Start date must be before end date' }; } // Check for reasonable date range (e.g., not more than 5 years) if (startDate && endDate) { const diffInDays = Math.abs(endDate.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24); if (diffInDays > 365 * 5) { return { valid: false, error: 'Date range spans more than 5 years. Please narrow your search.' }; } } // Check that dates aren't too far in the future const now = new Date(); const oneYearFromNow = new Date(now.getFullYear() + 1, now.getMonth(), now.getDate()); if (startDate && startDate > oneYearFromNow) { return { valid: false, error: 'Start date is too far in the future' }; } if (endDate && endDate > oneYearFromNow) { return { valid: false, error: 'End date is too far in the future' }; } return { valid: true, startDate, endDate }; } /** * Validate email address format */ export function validateEmail(email) { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return emailRegex.test(email); } /** * Validate and sanitize search query */ export function validateSearchQuery(query) { // Check length if (query.length > 1000) { return { valid: false, error: 'Search query is too long (max 1000 characters)' }; } // Check for problematic characters that might break OData const problematicChars = /[\x00-\x1F\x7F]/g; // Control characters if (problematicChars.test(query)) { return { valid: false, error: 'Search query contains invalid control characters' }; } // Sanitize by removing extra whitespace const sanitized = query .replace(/\s+/g, ' ') // Replace multiple spaces with single space .trim(); if (sanitized.length === 0) { return { valid: false, error: 'Search query cannot be empty' }; } return { valid: true, sanitized }; } /** * Validate folder name */ export function validateFolderName(name) { if (!name || name.trim().length === 0) { return { valid: false, error: 'Folder name cannot be empty' }; } // Check length if (name.length > 255) { return { valid: false, error: 'Folder name is too long (max 255 characters)' }; } // Check for invalid characters (based on Outlook restrictions) const invalidChars = /[\\/:*?"<>|]/; if (invalidChars.test(name)) { return { valid: false, error: 'Folder name contains invalid characters: \\ / : * ? " < > |' }; } return { valid: true }; } /** * Validate attachment size */ export function validateAttachmentSize(base64Content, maxSizeMB = 4) { // Estimate size from base64 (base64 is ~33% larger than binary) const estimatedSizeBytes = (base64Content.length * 3) / 4; const estimatedSizeMB = estimatedSizeBytes / (1024 * 1024); if (estimatedSizeMB > maxSizeMB) { return { valid: false, error: `Attachment size (${estimatedSizeMB.toFixed(2)}MB) exceeds the ${maxSizeMB}MB limit`, estimatedSizeMB }; } return { valid: true, estimatedSizeMB }; } /** * Validate OR query complexity */ export function validateOrQueryComplexity(orParts) { if (orParts.length > 10) { return { valid: false, error: 'OR query has too many parts (max 10). Please simplify your search.' }; } // Check if any individual part is too complex for (const part of orParts) { const filterCount = (part.match(/:/g) || []).length; if (filterCount > 5) { return { valid: false, error: 'Individual OR query parts are too complex. Please simplify.' }; } } return { valid: true }; } //# sourceMappingURL=validators.js.map