Manages the MeshCentral plugin lifecycle — loading, initializing, and exposing plugins to both the server-side Node.js environment and the browser-side Web UI.
| Export / Function | Description |
|---|---|
pluginHandler(parent) |
Factory function that returns the plugin handler object |
obj.plugins |
Map of loaded plugin instances keyed by short name |
obj.exports |
Map of each plugin's exported function names |
obj.callHook(hookName, ...args) |
Invokes a named hook across all loaded plugins (server-side) |
obj.prepExports() |
Serializes plugin exports into a self-executing JS string for browser injection |
obj.refreshJS(req, res) |
HTTP handler that streams the rebuilt pluginHandler to the browser without a server restart |
obj.addMeshCoreModules(modulesAdd) |
Injects plugin modules_meshcore JS files into the appropriate agent core bundles (Windows/Linux/AMT) |
obj.deviceViewPanel() |
Collects device tab header + page HTML from every plugin that implements on_device_header / on_device_page |
obj.isValidConfig(conf, url) |
Validates a plugin config.json against required fields before installation |
Client-side helpers (serialized into the browser bundle via prepExports):
callHook— fan-out hook invocation in the browserregisterPluginTab— injects a tab into the device panel (#p19headers/#p19pages)callPluginPage— tab switching logicaddPluginDlg/addPluginEx— UI dialog for installing plugins by URLrefreshPluginHandler— hot-reloads the plugin JS bundle without a page refresh
// Instantiated internally by MeshCentral during startup
const pluginHandler = require('./pluginHandler.js').pluginHandler(parent);
// Server-side: fire a hook on all loaded plugins
pluginHandler.callHook('onWebUIStartupEnd');
// Server-side: inject plugin modules into agent cores
pluginHandler.addMeshCoreModules(modulesAdd);
// HTTP route: serve live-updated plugin bundle to the browser
// GET /pluginHandler.js
app.get('/pluginHandler.js', (req, res) => pluginHandler.refreshJS(req, res));Plugins are loaded from <datapath>/plugins/<shortName>/ at startup via one of two paths:
- Database-driven — queries
db.getPlugins()for enabled (status == 1) records, then callsupdateMeshCore()once all async loads complete. - Config-driven — reads
settings.plugins.list(an array of short names) for local development or manual installs; loaded synchronously.
Each plugin module must export a factory function named after its shortName that receives the handler object.
⚠️ TheaddPluginDlgUI warns users that installing plugins from untrusted URLs may compromise server security.
- Source:
pluginHandler.js - Community: OpenMSP Slack