UNPKG

mcp-prompt-optimizer-local

Version:

Advanced Local Prompt Intelligence Engine - Complete privacy with sophisticated content analysis and optimization

171 lines (142 loc) 5.7 kB
/** * Simplified License Manager - Production Ready */ const https = require('https'); const fs = require('fs').promises; const path = require('path'); const os = require('os'); class SimplifiedLicenseManager { constructor() { this.cacheFile = path.join(os.homedir(), '.mcp-license-cache.json'); this.cacheExpiry = 24 * 60 * 60 * 1000; // 24 hours this.debug = process.env.MCP_DEBUG === 'true'; // Only debug if explicitly enabled } log(message) { if (this.debug) { console.log(`[DEBUG] ${message}`); } } async validateLicense() { const apiKey = process.env.OPTIMIZER_API_KEY; this.log(`Starting license validation...`); this.log(`API Key found: ${apiKey ? 'YES' : 'NO'}`); if (!apiKey) { return { valid: false, error: 'No API key found in OPTIMIZER_API_KEY environment variable' }; } this.log(`API Key: ${apiKey.substring(0, 25)}...`); // Validate format using original logic if (!this.isValidKeyFormat(apiKey)) { this.log(`Key format validation failed`); return { valid: false, error: 'Invalid API key format. Must start with "sk-local-" and contain "-basic-" or "-pro-"' }; } this.log(`Key format validation passed`); // Try cache first const cached = await this.getCachedValidation(apiKey); if (cached && cached.valid) { this.log(`Using cached validation - VALID`); return cached; } else if (cached) { this.log(`Cached validation found but INVALID - ignoring cache`); } this.log(`No valid cache found, using local validation...`); // For production, use local validation as primary method // This ensures reliability while backend integration can be added later if (this.isValidKeyFormat(apiKey)) { this.log(`Using local validation for production`); const result = { valid: true, type: apiKey.includes('-pro-') ? 'local_pro' : 'local_basic', features: [ 'local_processing', 'template_management', 'debugging_enhancement', 'content_analysis', 'technical_preservation' ], quota: apiKey.includes('-pro-') ? { unlimited: true } : { daily_limit: 5, remaining: 5 }, local_validation: true }; // Try to cache it await this.cacheValidation(apiKey, result); return result; } // If we get here, something is wrong return { valid: false, error: 'License validation failed' }; } // Use the exact validation logic from the original working version isValidKeyFormat(licenseKey) { if (!licenseKey || typeof licenseKey !== 'string') { this.log(`Key validation failed: not a string`); return false; } // Must start with sk-local- if (!licenseKey.startsWith('sk-local-')) { this.log(`Key validation failed: doesn't start with sk-local-`); return false; } // Must have basic or pro tier if (!licenseKey.includes('-basic-') && !licenseKey.includes('-pro-')) { this.log(`Key validation failed: doesn't contain -basic- or -pro-`); return false; } // Minimum length check if (licenseKey.length < 25) { this.log(`Key validation failed: too short (${licenseKey.length} chars)`); return false; } this.log(`Key format validation: PASSED`); return true; } async getCachedValidation(apiKey, allowExpired = false) { try { const cacheData = await fs.readFile(this.cacheFile, 'utf8'); const cache = JSON.parse(cacheData); this.log(`Cache file contents: ${JSON.stringify(cache, null, 2)}`); if (cache.apiKey !== apiKey) { this.log(`Cache key mismatch`); return null; } const age = Date.now() - new Date(cache.timestamp).getTime(); if (!allowExpired && age > this.cacheExpiry) { this.log(`Cache expired (${Math.round(age / 1000 / 60)} minutes old)`); return null; } this.log(`Cache found - Valid: ${cache.validation?.valid}`); return cache.validation; } catch (error) { this.log(`No cache available: ${error.message}`); return null; } } async cacheValidation(apiKey, validation) { try { const cacheData = { apiKey, validation, timestamp: new Date().toISOString() }; await fs.writeFile(this.cacheFile, JSON.stringify(cacheData, null, 2)); this.log(`Validation cached successfully`); } catch (error) { this.log(`Cache write failed: ${error.message}`); } } async clearCache() { try { await fs.unlink(this.cacheFile); this.log(`Cache file deleted: ${this.cacheFile}`); } catch (error) { this.log(`Cache clear failed (file may not exist): ${error.message}`); } } } module.exports = SimplifiedLicenseManager;