Add hook to allow adding custom api endpoints to Express routing

Martin Mädler committed Jan 27, 2023 at 12:23 UTC a8f89e10681100ffacf8683ea179a586aa2b038b
3 files changed +131 -100
docs/docs/meshcentral/plugins.md
+128 -8
@@ -1,16 +1,136 @@
1 -# Plugins
1 +# Plugins - Installation & Usage
2
3 !!!note
4 - Plugins are not supported, if you have problems with MeshCentral please disable all plugins before further troubleshooting.
4 + Plugins as such receive **no support** by the main developers of MeshCentral. If you experience problems with MeshCentral please make sure to **disable all plugins before further troubleshooting**!
5
6 -## Installation
6 +## Use Cases
7
8 -1. Enable plugins in the configuration and restart MC as described.
9 -2. Log into MC as full administrator.
8 +Certain feature requests may not be suitable for all MeshCentral users and thus are available as a plugin. Furthermore users can develop their own plugins - as described further below - to extend functionality or benefit from integrating the powerful MeshCentral into their existing application environment much better.
9 +
10 +## List of publically available plugins
11 +
12 +<https://github.com/topics/meshcentral-plugin>
13 +
14 +## Installation of a plugin
15 +
16 +1. First please make sure that you enable plugins in the configuration
17 + >"plugins": {
18 + > "enabled": true
19 + >},
20 +2. Restart MeshCentral in case you just enabled plugins in the configuration.
21 +2. Log into MeshCentral as full administrator.
22 3. Go my `My Server` -> `Plugins`, hit the Download plugin button.
11 -4. A dialog opens requesting an URL, put in: <https://github.com/ryanblenis/MeshCentral-ScriptTask>
23 +4. A dialog opens requesting an URL, e.g. put in: <https://github.com/ryanblenis/MeshCentral-ScriptTask>
24 5. The plugin pops up in the plugin list below the download button, you can now configure and enable/disable it.
25
14 -## List of plugins
26 +# Plugins - Development & Hooks
27
16 -<https://github.com/topics/meshcentral-plugin>
28 +!!!note
29 + Plugins as such receive **no support** by the main developers of MeshCentral. If you experience problems with MeshCentral please make sure to **disable all plugins before further troubleshooting**!
30 +
31 +## Overview
32 +
33 +Not all feature requests may be suitable for all MeshCentral users and thus can't be integrated into MeshCentral directly. Hwoever, Instead of maintaining a complete fork of MeshCentral it is so much easier to benefit from and extend MeshCentral's functionality by using hooks and writing plugins for it.
34 +
35 +## Anatomy of a plugin:
36 +
37 + - plugin_name/
38 + -- config.json
39 + -- plugin_name.js
40 + -- modules_meshcore/ // optional
41 + --- plugin_name.js // optional
42 +
43 +## Plugin Configuration File
44 +
45 +A valid JSON object within a file named `config.json` in the root folder of your project. An example:
46 +
47 + {
48 + "name": "Plugin Name",
49 + "shortName": "plugin_name",
50 + "version": "0.0.0",
51 + "author": "Author Name",
52 + "description": "Short Description of the plugin",
53 + "hasAdminPanel": false,
54 + "homepage": "https://www.example.com",
55 + "changelogUrl": "https://raw.githubusercontent.com/User/Project/master/changelog.md",
56 + "configUrl": "https://raw.githubusercontent.com/User/Project/master/config.json",
57 + "downloadUrl": "https://github.com/User/Project/archive/master.zip",
58 + "repository": {
59 + "type": "git",
60 + "url": "https://github.com/User/Project.git"
61 + },
62 + "versionHistoryUrl": "https://api.github.com/repos/User/Project/tags",
63 + "meshCentralCompat": ">0.4.3"
64 + }
65 +
66 +## Configuration File Properties
67 +
68 +| Field | Required | Type | Description |
69 +| ----------------- | -------- | ----------- | ------------------------------------------------------------ |
70 +| name | Yes | string | a human-readable name for the plugin |
71 +| shortName | Yes | string | an alphanumeric, unique short identifier for the plugin (will be used to access your functions throughout the project |
72 +| version | Yes | string | the current version of the plugin |
73 +| author | No | string | the author's name |
74 +| description | Yes | string | a short, human-readable description of what the plugin does |
75 +| hasAdminPanel | Yes | boolean | `true` or `false`, indicates whether or not the plugin will offer its own administrative interface |
76 +| homepage | Yes | string | the URL of the projects homepage |
77 +| changelogUrl | Yes | string | the URL to the changelog of the project |
78 +| configUrl | Yes | string | the URL to the config.json of the project |
79 +| downloadUrl | Yes | string | the URL to a ZIP of the project (used for installation/upgrades) |
80 +| repository | Yes | JSON object | contains the following attributes |
81 +| repository.type | Yes | string | valid values are `git` and in the future, `npm` will also be supported in the future |
82 +| repository.url | Yes | string | the URL to the project's repository |
83 +| versionHistoryUrl | No | string | the URL to the project's versions/tags |
84 +| meshCentralCompat | Yes | string | the minimum version string of required compatibility with the MeshCentral server, can be formatted as "0.1.2-c" or ">=0.1.2-c". Currently only supports minimum version, not full semantic checking. |
85 +
86 +## Plugin Hooks
87 +
88 +In essence, hooks are locations in the code which enable developers to tap into a module to either provide alternative behavior or to respond to an event.
89 +
90 +These are separated into the following categories depending on the type of functionality the plugin should offer.
91 +
92 +- Web UI, to modify the MeshCentral admin interface
93 +- Back End, to modify core functionality of the server and communicate with the Web UI layer as well as the Mesh Agent (Node) layer to send commands and data
94 +- Mesh Agent (Node), to introduce functionality to each agent
95 +
96 +### Web UI Hooks
97 +
98 +- `onDeviceRefreshEnd`: called when a device is selected in the MeshCentral web interface
99 +- `registerPluginTab`: callable when a device is selected in the MeshCentral web interface to register a new tab for plugin data, if required. Accepts an object, or function that returns an object, with the following properties: { tabId: "yourShortNameHere", tabTitle: "Your Display Name"}. A tab and div with the associated ID and title will be created for your use
100 +- `onDesktopDisconnect`: called when a remote desktop session is disconnected
101 +- `onWebUIStartupEnd`: called when the page has loaded for the first time after a login / refresh
102 +- `goPageStart`: called before page changes take effect. Passes 2 arguments (<page number> : int, <event> : Event)
103 +- `goPageEnd`: called after page changes take effect. Passes 2 arguments (<page number> : int, <event> : Event)
104 +
105 +#### Exports
106 +
107 +Any function can be exported to the Web UI layer by adding the name of the function to an `exports` array in the plugin object.
108 +
109 +### Back End Hooks
110 +
111 +- `server_startup`: called once when the server starts (or when the plugin is first installed)
112 +- `hook_agentCoreIsStable`: called once when an agent initially checks in
113 +- `hook_processAgentData`: called each time an agent transmits data back to the server
114 +- `hook_userLoggedIn`: called when a user has logged into the web interface
115 +- `hook_setupHttpHandlers`: called before all http handlers are setup
116 +
117 +### Mesh Agent
118 +
119 +Use of the optional file `plugin_name.js` in the optional folder `modules_meshcore` will include the file in the default meshcore file sent to each endpoint. This is useful to add functionality on each of the endpoints.
120 +
121 +## Structure
122 +
123 +Much of MeshCentral revolves around returning objects for your structures, and plugins are no different. Within your plugin you can traverse all the way up to the web server and MeshCentral Server classes to access all the functionality those layers provide. This is done by passing the current object to newly created objects, and assigning that reference to a `parent` variable within that object.
124 +
125 +
126 +## Versioning
127 +
128 +Versioning your plugin correctly and consistently is essential to ensure users of your plugin are prompted to upgrade when it is available. Semantic versioning is recommended.
129 +
130 +## Changelog
131 +
132 +A changelog is highly recommended so that your users know what's changed since their last version.
133 +
134 +## Sample Plugin
135 +
136 +[MeshCentral-Sample](https://github.com/ryanblenis/MeshCentral-Sample) is a simple plugin that, upon disconnecting from remote desktop, prompts the user to enter a manual event (note), pre-filled in with the date and timestamp.
plugin_development.md deleted
-92
@@ -1,92 +0,0 @@
1 -# Plugin Development
2 -
3 -## Overview
4 -
5 -## Anatomy of a plugin:
6 -
7 - - plugin_name/
8 - -- config.json
9 - -- plugin_name.js
10 - -- modules_meshcore/ // optional
11 - --- plugin_name.js // optional
12 -
13 -## Plugin Configuration File
14 -A valid JSON object within a file named `config.json` in the root folder of your project. An example:
15 -
16 - {
17 - "name": "Plugin Name",
18 - "shortName": "plugin_name",
19 - "version": "0.0.0",
20 - "author": "Author Name",
21 - "description": "Short Description of the plugin",
22 - "hasAdminPanel": false,
23 - "homepage": "https://www.example.com",
24 - "changelogUrl": "https://raw.githubusercontent.com/User/Project/master/changelog.md",
25 - "configUrl": "https://raw.githubusercontent.com/User/Project/master/config.json",
26 - "downloadUrl": "https://github.com/User/Project/archive/master.zip",
27 - "repository": {
28 - "type": "git",
29 - "url": "https://github.com/User/Project.git"
30 - },
31 - "versionHistoryUrl": "https://api.github.com/repos/User/Project/tags",
32 - "meshCentralCompat": ">0.4.3"
33 - }
34 -
35 -## Configuration File Properties
36 -| Field | Required | Type | Description
37 -|--|--|--|--|
38 -| name | Yes | string | a human-readable name for the plugin
39 -| shortName | Yes | string | an alphanumeric, unique short identifier for the plugin (will be used to access your functions throughout the project
40 -| version | Yes | string | the current version of the plugin
41 -| author | No | string | the author's name
42 -| description | Yes | string | a short, human-readable description of what the plugin does
43 -| hasAdminPanel | Yes | boolean | `true` or `false`, indicates whether or not the plugin will offer its own administrative interface
44 -| homepage | Yes | string | the URL of the projects homepage
45 -| changelogUrl | Yes | string | the URL to the changelog of the project
46 -| configUrl | Yes | string | the URL to the config.json of the project
47 -| downloadUrl | Yes | string | the URL to a ZIP of the project (used for installation/upgrades)
48 -| repository | Yes | JSON object | contains the following attributes
49 -| repository.type | Yes | string | valid values are `git` and in the future, `npm` will also be supported in the future
50 -| repository.url | Yes | string | the URL to the project's repository
51 -| versionHistoryUrl | No | string | the URL to the project's versions/tags
52 -| meshCentralCompat | Yes | string | the minimum version string of required compatibility with the MeshCentral server, can be formatted as "0.1.2-c" or ">=0.1.2-c". Currently only supports minimum version, not full semantic checking.
53 -
54 -## Plugin Hooks
55 -These are separated into the following categories depending on the type of functionality the plugin should offer.
56 -
57 -- Web UI, to modify the MeshCentral admin interface
58 -- Back End, to modify core functionality of the server and communicate with the Web UI layer as well as the Mesh Agent (Node) layer to send commands and data
59 -- Mesh Agent (Node), to introduce functionality to each agent
60 -
61 -### Web UI Hooks
62 -`onDeviceRefreshEnd`: called when a device is selected in the MeshCentral web interface
63 -`registerPluginTab`: callable when a device is selected in the MeshCentral web interface to register a new tab for plugin data, if required. Accepts an object, or function that returns an object, with the following properties: { tabId: "yourShortNameHere", tabTitle: "Your Display Name"}. A tab and div with the associated ID and title will be created for your use
64 -`onDesktopDisconnect`: called when a remote desktop session is disconnected
65 -`onWebUIStartupEnd`: called when the page has loaded for the first time after a login / refresh
66 -`goPageStart`: called before page changes take effect. Passes 2 arguments (<page number> : int, <event> : Event)
67 -`goPageEnd`: called after page changes take effect. Passes 2 arguments (<page number> : int, <event> : Event)
68 -
69 -#### Exports
70 -Any function can be exported to the Web UI layer by adding the name of the function to an `exports` array in the plugin object.
71 -
72 -### Back End Hooks
73 -`server_startup`: called once when the server starts (or when the plugin is first installed)
74 -`hook_agentCoreIsStable`: called once when an agent initially checks in
75 -`hook_processAgentData`: called each time an agent transmits data back to the server
76 -`hook_userLoggedIn`: called when a user has logged into the web interface
77 -
78 -### Mesh Agent
79 -Use of the optional file `plugin_name.js` in the optional folder `modules_meshcore` will include the file in the default meshcore file sent to each endpoint. This is useful to add functionality on each of the endpoints.
80 -
81 -## Structure
82 -Much of MeshCentral revolves around returning objects for your structures, and plugins are no different. Within your plugin you can traverse all the way up to the web server and MeshCentral Server classes to access all the functionality those layers provide. This is done by passing the current object to newly created objects, and assigning that reference to a `parent` variable within that object.
83 -
84 -
85 -## Versioning
86 -Versioning your plugin correctly and consistently is essential to ensure users of your plugin are prompted to upgrade when it is available. Semantic versioning is recommended.
87 -
88 -## Changelog
89 -A changelog is highly recommended so that your users know what's changed since their last version.
90 -
91 -## Sample Plugin
92 -[MeshCentral-Sample](https://github.com/ryanblenis/MeshCentral-Sample) is a simple plugin that, upon disconnecting from remote desktop, prompts the user to enter a manual event (note), pre-filled in with the date and timestamp.
webserver.js
+3
@@ -6341,6 +6341,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
6341 }
6342
6343 // Setup all HTTP handlers
6344 + if (parent.parent.pluginHandler != null) {
6345 + parent.parent.pluginHandler.callHook('hook_setupHttpHandlers', obj, parent);
6346 + }
6347 if (parent.multiServer != null) { obj.app.ws('/meshserver.ashx', function (ws, req) { parent.multiServer.CreatePeerInServer(parent.multiServer, ws, req, obj.args.tlsoffload == null); }); }
6348 for (var i in parent.config.domains) {
6349 if ((parent.config.domains[i].dns != null) || (parent.config.domains[i].share != null)) { continue; } // This is a subdomain with a DNS name, no added HTTP bindings needed.