fortify2-js
Version:
MOST POWERFUL JavaScript Security Library! Military-grade cryptography + 19 enhanced object methods + quantum-resistant algorithms + perfect TypeScript support. More powerful than Lodash with built-in security.
313 lines (309 loc) • 11.6 kB
JavaScript
'use strict';
var PluginRegistry = require('../../plugins/PluginRegistry.js');
var PluginEngine = require('../../plugins/PluginEngine.js');
var Logger = require('../../utils/Logger.js');
/**
* PluginManager - Handles all plugin-related operations for FastApi.ts
* Manages plugin registration, execution, and monitoring
*/
class PluginManager {
constructor(dependencies) {
this.dependencies = dependencies;
this.initializePluginSystem();
}
/**
* Initialize the plugin system
*/
initializePluginSystem() {
Logger.logger.debug("plugins", "Initializing plugin system...");
// Initialize plugin registry
this.pluginRegistry = new PluginRegistry.PluginRegistry(this.dependencies.cacheManager.getCache(), this.dependencies.cluster);
// Initialize plugin engine
this.pluginEngine = new PluginEngine.PluginEngine(this.pluginRegistry, this.dependencies.cacheManager.getCache(), this.dependencies.cluster);
Logger.logger.debug("plugins", "Plugin system initialized");
}
/**
* Get plugin registry instance
*/
getPluginRegistry() {
return this.pluginRegistry;
}
/**
* Get plugin engine instance
*/
getPluginEngine() {
return this.pluginEngine;
}
/**
* Add plugin monitoring endpoints to the Express app
*/
addPluginMonitoringEndpoints(basePoint) {
// Plugin registry status endpoint
this.dependencies.app.get(basePoint + "/health/plugins", async (req, res) => {
try {
const registryStats = this.getPluginRegistryStats();
const engineStats = this.getPluginEngineStats();
res.json({
timestamp: new Date().toISOString(),
plugins: {
registry: registryStats,
engine: engineStats,
status: "healthy",
},
});
}
catch (error) {
res.status(500).json({
error: "Failed to get plugin statistics",
message: error.message,
});
}
});
// Individual plugin statistics endpoint
this.dependencies.app.get(basePoint + "/plugins/:pluginId/stats", async (req, res) => {
try {
const { pluginId } = req.params;
const stats = this.getPluginStats(pluginId);
if (!stats) {
return res.status(404).json({
error: "Plugin not found",
pluginId,
});
}
res.json({
timestamp: new Date().toISOString(),
pluginId,
stats,
});
}
catch (error) {
res.status(500).json({
error: "Failed to get plugin statistics",
message: error.message,
});
}
});
// Plugin management endpoint - register plugin
this.dependencies.app.post(basePoint + "/plugins/register", async (req, res) => {
try {
const { pluginConfig } = req.body;
if (!pluginConfig) {
return res.status(400).json({
error: "Plugin configuration is required",
});
}
// Validate plugin configuration
if (!pluginConfig.id ||
!pluginConfig.name ||
!pluginConfig.version) {
return res.status(400).json({
error: "Plugin must have id, name, and version",
});
}
// Check if plugin already exists
const existingPlugin = this.getPlugin(pluginConfig.id);
if (existingPlugin) {
return res.status(409).json({
error: "Plugin already registered",
pluginId: pluginConfig.id,
});
}
// For security, only allow registration of pre-approved plugin types
const allowedPluginTypes = [
"performance",
"cache",
"monitoring",
];
if (!allowedPluginTypes.includes(pluginConfig.type)) {
return res.status(403).json({
error: "Plugin type not allowed for dynamic registration",
allowedTypes: allowedPluginTypes,
});
}
// Create a simple plugin instance from configuration
const dynamicPlugin = this.createDynamicPlugin(pluginConfig);
// Register the dynamic plugin
await this.registerPlugin(dynamicPlugin);
res.json({
success: true,
message: `Plugin ${pluginConfig.id} registered successfully`,
pluginId: pluginConfig.id,
type: pluginConfig.type,
registeredAt: new Date().toISOString(),
});
}
catch (error) {
res.status(500).json({
error: "Failed to register plugin",
message: error.message,
});
}
});
// Plugin management endpoint - unregister plugin
this.dependencies.app.delete(basePoint + "/plugins/:pluginId", async (req, res) => {
try {
const { pluginId } = req.params;
await this.unregisterPlugin(pluginId);
res.json({
success: true,
message: `Plugin ${pluginId} unregistered successfully`,
});
}
catch (error) {
res.status(500).json({
error: "Failed to unregister plugin",
message: error.message,
});
}
});
}
/**
* Create a dynamic plugin from configuration
*/
createDynamicPlugin(pluginConfig) {
return {
id: pluginConfig.id,
name: pluginConfig.name,
version: pluginConfig.version,
type: pluginConfig.type,
priority: pluginConfig.priority || 2,
isAsync: pluginConfig.isAsync !== false,
isCacheable: pluginConfig.isCacheable === true,
maxExecutionTime: pluginConfig.maxExecutionTime || 1000,
execute: async (context) => {
// Simple execution logic for dynamic plugins
const startTime = performance.now();
// Basic plugin functionality based on type
let result = { success: true };
if (pluginConfig.type === "performance") {
result.metrics = {
executionTime: performance.now() - startTime,
timestamp: Date.now(),
route: context.req.path,
};
}
else if (pluginConfig.type === "cache") {
result.cacheKey = `dynamic:${context.req.path}`;
result.cacheable = true;
}
else if (pluginConfig.type === "monitoring") {
result.monitoring = {
requestId: context.executionId,
userAgent: context.req.headers["user-agent"],
ip: context.req.ip,
};
}
return {
success: true,
executionTime: performance.now() - startTime,
data: result,
shouldContinue: true,
};
},
};
}
/**
* Register a plugin with the server
*/
async registerPlugin(plugin) {
await this.pluginRegistry.register(plugin);
}
/**
* Unregister a plugin from the server
*/
async unregisterPlugin(pluginId) {
await this.pluginRegistry.unregister(pluginId);
}
/**
* Get plugin by ID
*/
getPlugin(pluginId) {
return this.pluginRegistry.getPlugin(pluginId);
}
/**
* Get all registered plugins
*/
getAllPlugins() {
return this.pluginRegistry.getAllPlugins();
}
/**
* Get plugins by type
*/
getPluginsByType(type) {
return this.pluginRegistry.getPluginsByType(type);
}
/**
* Get plugin execution statistics
*/
getPluginStats(pluginId) {
if (pluginId) {
return this.pluginRegistry.getPluginStats(pluginId);
}
return this.pluginRegistry.getAllStats();
}
/**
* Get plugin registry statistics
*/
getPluginRegistryStats() {
return this.pluginRegistry.getRegistryStats();
}
/**
* Get plugin engine statistics
*/
getPluginEngineStats() {
return this.pluginEngine.getEngineStats();
}
/**
* Initialize built-in plugins
*/
async initializeBuiltinPlugins() {
try {
// Import and register built-in plugins
const { JWTAuthPlugin } = await Promise.resolve().then(function () { return require('../../plugins/builtin/JWTAuthPlugin.js'); });
const { ResponseTimePlugin } = await Promise.resolve().then(function () { return require('../../plugins/builtin/ResponseTimePlugin.js'); });
const { SmartCachePlugin } = await Promise.resolve().then(function () { return require('../../plugins/builtin/SmartCachePlugin.js'); });
// Register security plugins
await this.registerPlugin(new JWTAuthPlugin());
// Register performance plugins
await this.registerPlugin(new ResponseTimePlugin());
// Register cache plugins
await this.registerPlugin(new SmartCachePlugin());
Logger.logger.debug("plugins", "Built-in plugins initialized successfully");
}
catch (error) {
console.error("Failed to initialize built-in plugins:", error.message);
}
}
/**
* Get plugin system health status
*/
getPluginSystemHealth() {
try {
const registryStats = this.getPluginRegistryStats();
const engineStats = this.getPluginEngineStats();
return {
status: "healthy",
timestamp: new Date().toISOString(),
registry: {
totalPlugins: registryStats.totalPlugins,
activePlugins: registryStats.activePlugins,
averageExecutionTime: registryStats.averageExecutionTime,
},
engine: {
totalExecutions: engineStats.totalExecutions,
successRate: engineStats.successRate,
averageExecutionTime: engineStats.averageExecutionTime,
},
};
}
catch (error) {
return {
status: "unhealthy",
timestamp: new Date().toISOString(),
error: error.message,
};
}
}
}
exports.PluginManager = PluginManager;
//# sourceMappingURL=PluginManager.js.map