@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
JavaScript
/**
* 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 };