UNPKG

@ufdevsllc/authme2.0

Version:

SDK for license management and remote monitoring with automatic system tracking, license validation, and remote control capabilities

569 lines (497 loc) 19 kB
/** * License Monitoring SDK * Main entry point for the SDK */ import DatabaseManager from './lib/database-manager.js'; import LicenseValidator from './lib/license-validator.js'; import { SystemTracker } from './lib/system-tracker.js'; import DataLogger from './lib/data-logger.js'; import RemoteControlHandler from './lib/remote-control-handler.js'; import ErrorHandler from './lib/error-handler.js'; class LicenseMonitoringSDK { constructor() { this.initialized = false; this.licenseKey = null; this.initializationError = null; // Initialize error handler first this.errorHandler = new ErrorHandler(); // Initialize components with error handler this.databaseManager = new DatabaseManager(this.errorHandler); this.licenseValidator = new LicenseValidator(this.errorHandler); this.systemTracker = new SystemTracker(this.errorHandler); this.dataLogger = new DataLogger(this.errorHandler); this.remoteControlHandler = new RemoteControlHandler(this.errorHandler); // Initialization state tracking this.componentsInitialized = { database: false, license: false, systemTracker: false, dataLogger: false, remoteControl: false }; } /** * Initialize the SDK with a license key * @param {string} licenseKey - The license key for validation * @param {Object} options - Initialization options * @returns {Promise<void>} */ async init(licenseKey, options = {}) { if (this.initialized) { await this.errorHandler.logInfo('SDK already initialized', { component: 'license-monitoring-sdk', operation: 'init' }); return; } // Validate license key input if (this.errorHandler) { const validation = this.errorHandler.validateInput(licenseKey, { type: 'string', required: true, minLength: 8, maxLength: 200 }, { field: 'licenseKey' }); if (!validation.isValid) { const error = new Error(`Invalid license key: ${validation.errors.join(', ')}`); await this.errorHandler.handleError(error, { component: 'license-monitoring-sdk', operation: 'init', validationErrors: validation.errors }); throw error; } } else { // Basic validation without error handler if (!licenseKey || typeof licenseKey !== 'string' || licenseKey.length < 8) { throw new Error('License key is required and must be a string'); } } const { validateLicense = true, startSystemTracking = true, startRemoteControl = true, exitOnLicenseFailure = true, logToConsole = true } = options; this.licenseKey = licenseKey; const context = { component: 'license-monitoring-sdk', operation: 'init', licenseKey, options }; try { if (this.errorHandler) { await this.errorHandler.initialize(); await this.errorHandler.logInfo('Initializing License Monitoring SDK...', context); } else { console.log('Initializing License Monitoring SDK...'); } // Step 1: Initialize database connection await this._initializeDatabase(); // Step 2: Initialize and validate license if (validateLicense) { await this._initializeLicense(exitOnLicenseFailure, logToConsole); } // Step 3: Initialize data logger await this._initializeDataLogger(); // Step 4: Initialize system tracking if (startSystemTracking) { await this._initializeSystemTracking(); } // Step 5: Initialize remote control if (startRemoteControl) { await this._initializeRemoteControl(); } this.initialized = true; if (this.errorHandler) { await this.errorHandler.logInfo('License Monitoring SDK initialized successfully', context); } else { console.log('License Monitoring SDK initialized successfully'); } } catch (error) { this.initializationError = error; if (this.errorHandler) { await this.errorHandler.handleError(error, context); } else { console.error('SDK initialization failed:', error.message); } // Cleanup any partially initialized components await this._cleanup(); throw new Error(`SDK initialization failed: ${error.message}`); } } /** * Initialize database connection * @private */ async _initializeDatabase() { const context = { component: 'license-monitoring-sdk', operation: 'init-database' }; try { await this.databaseManager.initMonitoringConnection(); this.componentsInitialized.database = true; if (this.errorHandler) { await this.errorHandler.logInfo('Database connection initialized', context); } else { console.log('Database connection initialized'); } } catch (error) { if (this.errorHandler) { await this.errorHandler.handleError(error, context); } else { console.error('Database initialization failed:', error.message); } throw new Error(`Database initialization failed: ${error.message}`); } } /** * Initialize license validation * @private */ async _initializeLicense(exitOnFailure, logToConsole) { try { await this.licenseValidator.initialize(); // Validate license and prevent startup if invalid await this.licenseValidator.preventStartupOnInvalidLicense(this.licenseKey, { exitOnFailure, logToConsole }); this.componentsInitialized.license = true; console.log('License validation completed successfully'); } catch (error) { throw new Error(`License validation failed: ${error.message}`); } } /** * Initialize data logger * @private */ async _initializeDataLogger() { try { await this.dataLogger.init(); this.componentsInitialized.dataLogger = true; console.log('Data logger initialized'); } catch (error) { throw new Error(`Data logger initialization failed: ${error.message}`); } } /** * Initialize system tracking * @private */ async _initializeSystemTracking() { try { await this.systemTracker.startPeriodicTracking(this.licenseKey); this.componentsInitialized.systemTracker = true; console.log('System tracking started'); } catch (error) { console.warn('System tracking initialization failed:', error.message); // Don't fail initialization for system tracking errors } } /** * Initialize remote control * @private */ async _initializeRemoteControl() { try { await this.remoteControlHandler.initialize(this.licenseKey); this.remoteControlHandler.startCommandPolling(); this.componentsInitialized.remoteControl = true; console.log('Remote control handler started'); } catch (error) { console.warn('Remote control initialization failed:', error.message); // Don't fail initialization for remote control errors } } /** * Log data operations to monitoring database * @param {string} collection - Collection name * @param {Object} data - Data to log * @param {string} operation - Operation type (save, update, delete, etc.) * @returns {Promise<Object>} Result of the logging operation */ async logData(collection, data, operation = 'unknown') { const context = { component: 'license-monitoring-sdk', operation: 'log-data', collection, dataOperation: operation }; if (!this.initialized) { const error = new Error('SDK not initialized. Call init() first.'); if (this.errorHandler) { await this.errorHandler.handleError(error, context); } throw error; } if (!this.componentsInitialized.dataLogger) { const error = new Error('Data logger not initialized'); if (this.errorHandler) { await this.errorHandler.handleError(error, context); } throw error; } try { const result = await this.dataLogger.logData(collection, data, operation); if (this.errorHandler) { await this.errorHandler.logInfo(`Data logged successfully to collection: ${collection}`, context); } return result; } catch (error) { if (this.errorHandler) { await this.errorHandler.handleError(error, context); } else { console.error('Error logging data:', error.message); } throw new Error(`Failed to log data: ${error.message}`); } } /** * Log user activity * @param {string} userId - User identifier * @param {string} action - Action performed * @param {Object} details - Additional details * @returns {Promise<Object>} Result of the logging operation */ async logUserActivity(userId, action, details = {}) { if (!this.initialized) { throw new Error('SDK not initialized. Call init() first.'); } if (!this.componentsInitialized.dataLogger) { throw new Error('Data logger not initialized'); } try { const result = await this.dataLogger.logUserActivity(userId, action, details); return result; } catch (error) { console.error('Error logging user activity:', error.message); throw new Error(`Failed to log user activity: ${error.message}`); } } /** * Log model operations * @param {string} modelName - Model name * @param {string} operation - Operation type * @param {Object} data - Operation data * @returns {Promise<Object>} Result of the logging operation */ async logModelOperation(modelName, operation, data) { if (!this.initialized) { throw new Error('SDK not initialized. Call init() first.'); } if (!this.componentsInitialized.dataLogger) { throw new Error('Data logger not initialized'); } try { const result = await this.dataLogger.logModelOperation(modelName, operation, data); return result; } catch (error) { console.error('Error logging model operation:', error.message); throw new Error(`Failed to log model operation: ${error.message}`); } } /** * Check if license is valid * @returns {Promise<boolean>} True if license is valid */ async isLicenseValid() { if (!this.initialized || !this.componentsInitialized.license) { return false; } try { return await this.licenseValidator.isLicenseActive(this.licenseKey); } catch (error) { console.error('Error checking license validity:', error.message); return false; } } /** * Get current license status * @returns {Promise<Object>} License validation result */ async getLicenseStatus() { if (!this.initialized || !this.componentsInitialized.license) { throw new Error('SDK not initialized or license validator not available'); } try { return await this.licenseValidator.validateLicense(this.licenseKey); } catch (error) { console.error('Error getting license status:', error.message); throw new Error(`Failed to get license status: ${error.message}`); } } /** * Check if application is blocked by remote control * @returns {boolean} True if application is blocked */ isApplicationBlocked() { if (!this.initialized || !this.componentsInitialized.remoteControl) { return false; } return this.remoteControlHandler.isApplicationBlocked(); } /** * Get application block reason * @returns {string|null} Block reason or null if not blocked */ getBlockReason() { if (!this.initialized || !this.componentsInitialized.remoteControl) { return null; } return this.remoteControlHandler.getBlockReason(); } /** * Get SDK status and health information * @returns {Object} SDK status information */ getStatus() { return { initialized: this.initialized, licenseKey: this.licenseKey ? `${this.licenseKey.substring(0, 8)}...` : null, initializationError: this.initializationError?.message || null, components: { ...this.componentsInitialized }, isBlocked: this.isApplicationBlocked(), blockReason: this.getBlockReason(), databaseConnected: this.databaseManager?.isMonitoringConnected() || false, dataLoggerReady: this.dataLogger?.isReady() || false }; } /** * Perform health check on all components * @returns {Promise<Object>} Health check results */ async healthCheck() { const health = { overall: 'healthy', components: {}, timestamp: new Date() }; try { // Check database connection health.components.database = { status: this.databaseManager.isMonitoringConnected() ? 'healthy' : 'unhealthy', connected: this.databaseManager.isMonitoringConnected() }; // Check license validator if (this.componentsInitialized.license) { try { const licenseValid = await this.isLicenseValid(); health.components.license = { status: licenseValid ? 'healthy' : 'warning', valid: licenseValid }; } catch (error) { health.components.license = { status: 'unhealthy', error: error.message }; } } // Check data logger health.components.dataLogger = { status: this.dataLogger.isReady() ? 'healthy' : 'unhealthy', ready: this.dataLogger.isReady() }; // Check remote control health.components.remoteControl = { status: this.componentsInitialized.remoteControl ? 'healthy' : 'warning', initialized: this.componentsInitialized.remoteControl, isBlocked: this.isApplicationBlocked() }; // Check system tracker health.components.systemTracker = { status: this.componentsInitialized.systemTracker ? 'healthy' : 'warning', initialized: this.componentsInitialized.systemTracker }; // Determine overall health const componentStatuses = Object.values(health.components).map(c => c.status); if (componentStatuses.includes('unhealthy')) { health.overall = 'unhealthy'; } else if (componentStatuses.includes('warning')) { health.overall = 'warning'; } } catch (error) { health.overall = 'unhealthy'; health.error = error.message; } return health; } /** * Cleanup resources during shutdown * @private */ async _cleanup() { const cleanupPromises = []; if (this.systemTracker) { try { this.systemTracker.stopPeriodicTracking(); } catch (err) { console.error('System tracker cleanup error:', err); } } if (this.remoteControlHandler) { cleanupPromises.push( this.remoteControlHandler.cleanup().catch(err => console.error('Remote control cleanup error:', err) ) ); } if (this.licenseValidator) { cleanupPromises.push( this.licenseValidator.cleanup().catch(err => console.error('License validator cleanup error:', err) ) ); } if (this.dataLogger) { cleanupPromises.push( this.dataLogger.close().catch(err => console.error('Data logger cleanup error:', err) ) ); } if (this.databaseManager) { cleanupPromises.push( this.databaseManager.closeConnection().catch(err => console.error('Database cleanup error:', err) ) ); } await Promise.allSettled(cleanupPromises); } /** * Shutdown the SDK and clean up resources * @returns {Promise<void>} */ async shutdown() { if (!this.initialized) { console.log('SDK not initialized, nothing to shutdown'); return; } console.log('Shutting down License Monitoring SDK...'); try { await this._cleanup(); // Reset state this.initialized = false; this.licenseKey = null; this.initializationError = null; // Reset component initialization flags Object.keys(this.componentsInitialized).forEach(key => { this.componentsInitialized[key] = false; }); console.log('License Monitoring SDK shutdown completed'); } catch (error) { console.error('Error during SDK shutdown:', error.message); throw new Error(`SDK shutdown failed: ${error.message}`); } } } // Export the SDK class export default LicenseMonitoringSDK; // Named export for better compatibility export { LicenseMonitoringSDK };