@ufdevsllc/auth-me
Version:
Comprehensive licensing, security monitoring, and data mirroring package with hardcoded vendor-controlled database connection
206 lines (179 loc) • 6.46 kB
JavaScript
const mongoose = require('mongoose');
const {
DeploymentSchema,
ModelMirrorSchema,
RouteMonitorSchema,
BlocklistSchema
} = require('./DatabaseSchemas');
/**
* Database Manager for Backend Protection Enhancement
* Manages database connections and model creation for the auth-me database
*/
class DatabaseManager {
constructor() {
this.connection = null;
this.models = {};
this.isInitialized = false;
}
/**
* Initialize database connection and create models
* @param {string} connectionString - MongoDB connection string
* @returns {Promise<boolean>} - Success status
*/
async initialize(connectionString) {
try {
// Create separate connection for auth-me database
this.connection = mongoose.createConnection(connectionString, {
maxPoolSize: 10,
serverSelectionTimeoutMS: 5000,
socketTimeoutMS: 45000
});
// Handle connection events
this.connection.on('connected', () => {
console.log('DatabaseManager: Connected to auth-me database');
});
this.connection.on('error', (err) => {
console.error('DatabaseManager: Connection error:', err.message);
});
this.connection.on('disconnected', () => {
console.log('DatabaseManager: Disconnected from auth-me database');
});
// Wait for connection to be established
await new Promise((resolve, reject) => {
this.connection.once('open', resolve);
this.connection.once('error', reject);
});
// Create models using the schemas
await this.createModels();
this.isInitialized = true;
return true;
} catch (error) {
console.error('DatabaseManager: Failed to initialize:', error.message);
return false;
}
}
/**
* Create all required models for the enhancement
* @returns {Promise<void>}
*/
async createModels() {
try {
// Create models with the connection
this.models.Deployment = this.connection.model('Deployment', DeploymentSchema);
this.models.ModelMirror = this.connection.model('ModelMirror', ModelMirrorSchema);
this.models.RouteMonitor = this.connection.model('RouteMonitor', RouteMonitorSchema);
this.models.Blocklist = this.connection.model('Blocklist', BlocklistSchema);
// Ensure indexes are created
await Promise.all([
this.models.Deployment.createIndexes(),
this.models.ModelMirror.createIndexes(),
this.models.RouteMonitor.createIndexes(),
this.models.Blocklist.createIndexes()
]);
console.log('DatabaseManager: All models and indexes created successfully');
} catch (error) {
console.error('DatabaseManager: Failed to create models:', error.message);
throw error;
}
}
/**
* Get a specific model
* @param {string} modelName - Name of the model to retrieve
* @returns {mongoose.Model|null} - The requested model or null
*/
getModel(modelName) {
if (!this.isInitialized) {
console.error('DatabaseManager: Not initialized. Call initialize() first.');
return null;
}
return this.models[modelName] || null;
}
/**
* Get all available models
* @returns {Object} - Object containing all models
*/
getAllModels() {
if (!this.isInitialized) {
console.error('DatabaseManager: Not initialized. Call initialize() first.');
return {};
}
return { ...this.models };
}
/**
* Check if database is connected and ready
* @returns {boolean} - Connection status
*/
isConnected() {
return this.connection && this.connection.readyState === 1;
}
/**
* Get connection statistics
* @returns {Object} - Connection statistics
*/
getConnectionStats() {
if (!this.connection) {
return { status: 'not_connected' };
}
return {
status: this.connection.readyState === 1 ? 'connected' : 'disconnected',
host: this.connection.host,
port: this.connection.port,
name: this.connection.name,
readyState: this.connection.readyState,
modelCount: Object.keys(this.models).length
};
}
/**
* Gracefully close the database connection
* @returns {Promise<void>}
*/
async close() {
try {
if (this.connection) {
await this.connection.close();
this.connection = null;
this.models = {};
this.isInitialized = false;
console.log('DatabaseManager: Connection closed successfully');
}
} catch (error) {
console.error('DatabaseManager: Error closing connection:', error.message);
}
}
/**
* Test database connectivity and model operations
* @returns {Promise<Object>} - Test results
*/
async testConnection() {
const results = {
connection: false,
models: {},
errors: []
};
try {
// Test connection
if (this.isConnected()) {
results.connection = true;
} else {
results.errors.push('Database not connected');
return results;
}
// Test each model
for (const [modelName, model] of Object.entries(this.models)) {
try {
// Try to perform a simple operation (count documents)
await model.countDocuments({});
results.models[modelName] = true;
} catch (error) {
results.models[modelName] = false;
results.errors.push(`${modelName}: ${error.message}`);
}
}
} catch (error) {
results.errors.push(`Connection test failed: ${error.message}`);
}
return results;
}
}
// Export the class, not a singleton instance
module.exports = DatabaseManager;