const database = require('./database'); const crypto = require('crypto'); class ConfigManager { constructor() { this.encryptionKey = null; } getOrCreateEncryptionKey() { // Lazy initialization - only create key when first needed if (this.encryptionKey) { return this.encryptionKey; } // In production, this should be stored securely (environment variable or secure file) // For now, we'll generate a random key and store it in the database try { let key = database.getConfig('_encryption_key'); if (!key) { key = crypto.randomBytes(32).toString('hex'); database.setConfig('_encryption_key', key); } this.encryptionKey = key; return key; } catch (error) { // If database not ready, generate temporary key console.warn('Database not ready, using temporary encryption key'); this.encryptionKey = crypto.randomBytes(32).toString('hex'); return this.encryptionKey; } } encrypt(text) { if (!text) return null; try { const key = this.getOrCreateEncryptionKey(); const iv = crypto.randomBytes(16); const cipher = crypto.createCipheriv( 'aes-256-cbc', Buffer.from(key, 'hex'), iv ); let encrypted = cipher.update(text, 'utf8', 'hex'); encrypted += cipher.final('hex'); return iv.toString('hex') + ':' + encrypted; } catch (error) { console.error('Encryption error:', error.message); return null; } } decrypt(text) { if (!text) return null; try { const key = this.getOrCreateEncryptionKey(); const parts = text.split(':'); const iv = Buffer.from(parts[0], 'hex'); const encrypted = parts[1]; const decipher = crypto.createDecipheriv( 'aes-256-cbc', Buffer.from(key, 'hex'), iv ); let decrypted = decipher.update(encrypted, 'hex', 'utf8'); decrypted += decipher.final('utf8'); return decrypted; } catch (error) { console.error('Decryption error:', error.message); return null; } } get(key) { try { const value = database.getConfig(key); // Decrypt token if it's the auth token if (key === 'authToken' && value) { return this.decrypt(value); } return value; } catch (error) { console.warn(`Config.get('${key}') failed:`, error.message); return null; } } set(key, value) { try { // Encrypt token if it's the auth token if (key === 'authToken' && value) { value = this.encrypt(value); } database.setConfig(key, value); } catch (error) { console.error(`Config.set('${key}') failed:`, error.message); } } getAll() { try { const config = database.getConfig(); // Decrypt auth token if present if (config.authToken) { config.authToken = this.decrypt(config.authToken); } return config; } catch (error) { console.warn('Config.getAll() failed:', error.message); return {}; } } setMultiple(configObj) { try { // Encrypt auth token if present if (configObj.authToken) { configObj.authToken = this.encrypt(configObj.authToken); } database.setConfigMultiple(configObj); } catch (error) { console.error('Config.setMultiple() failed:', error.message); } } isAuthenticated() { try { const token = this.get('authToken'); const expiry = this.get('tokenExpiry'); if (!token) return false; if (!expiry) return false; const expiryDate = new Date(expiry); const now = new Date(); return now < expiryDate; } catch (error) { return false; } } clearAuth() { try { this.set('authToken', ''); this.set('tokenExpiry', ''); } catch (error) { console.error('Failed to clear auth:', error.message); } } } module.exports = new ConfigManager();