2019-10-08 04:18:40 -04:00
/ * *
* @ description MeshCentral plugin module
* @ author Ryan Blenis
* @ copyright
* @ license Apache - 2.0
* @ version v0 . 0.1
* /
/*xjslint node: true */
/*xjslint plusplus: true */
/*xjslint maxlen: 256 */
/*jshint node: true */
/*jshint strict: false */
/*jshint esversion: 6 */
"use strict" ;
2019-11-05 00:11:14 -05:00
require ( 'promise' ) ;
2019-10-08 04:18:40 -04:00
module . exports . pluginHandler = function ( parent ) {
var obj = { } ;
obj . fs = require ( 'fs' ) ;
obj . path = require ( 'path' ) ;
obj . parent = parent ;
obj . pluginPath = obj . parent . path . join ( obj . parent . datapath , 'plugins' ) ;
obj . plugins = { } ;
obj . exports = { } ;
2019-11-01 16:49:18 -04:00
obj . loadList = obj . parent . config . settings . plugins . list ; // For local development / manual install, not from DB
2019-10-10 14:13:25 -04:00
if ( typeof obj . loadList != 'object' ) {
obj . loadList = { } ;
2019-11-01 16:49:18 -04:00
parent . db . getPlugins ( function ( err , plugins ) {
plugins . forEach ( function ( plugin ) {
if ( plugin . status != 1 ) return ;
if ( obj . fs . existsSync ( obj . pluginPath + '/' + plugin . shortName ) ) {
try {
obj . plugins [ plugin . shortName ] = require ( obj . pluginPath + '/' + plugin . shortName + '/' + plugin . shortName + '.js' ) [ plugin . shortName ] ( obj ) ;
obj . exports [ plugin . shortName ] = obj . plugins [ plugin . shortName ] . exports ;
} catch ( e ) {
console . log ( "Error loading plugin: " + plugin . shortName + " (" + e + "). It has been disabled." , e . stack ) ;
}
2019-11-22 14:25:13 -05:00
try { // try loading local info about plugin to database (if it changed locally)
var plugin _config = obj . fs . readFileSync ( obj . pluginPath + '/' + plugin . shortName + '/config.json' ) ;
plugin _config = JSON . parse ( plugin _config ) ;
parent . db . updatePlugin ( plugin . _id , plugin _config ) ;
} catch ( e ) { console . log ( 'Plugin config file for ' + plugin . name + ' could not be parsed.' ) ; }
2019-11-01 16:49:18 -04:00
}
obj . parent . updateMeshCore ( ) ; // db calls are delayed, lets inject here once we're ready
} ) ;
} ) ;
} else {
obj . loadList . forEach ( function ( plugin , index ) {
if ( obj . fs . existsSync ( obj . pluginPath + '/' + plugin ) ) {
try {
obj . plugins [ plugin ] = require ( obj . pluginPath + '/' + plugin + '/' + plugin + '.js' ) [ plugin ] ( obj ) ;
obj . exports [ plugin ] = obj . plugins [ plugin ] . exports ;
} catch ( e ) {
console . log ( "Error loading plugin: " + plugin + " (" + e + "). It has been disabled." , e . stack ) ;
}
2019-10-10 14:13:25 -04:00
}
2019-11-01 16:49:18 -04:00
} ) ;
}
2019-10-10 14:13:25 -04:00
obj . prepExports = function ( ) {
var str = 'function() {\r\n' ;
str += ' var obj = {};\r\n' ;
for ( const p of Object . keys ( obj . plugins ) ) {
2019-11-02 06:27:39 -04:00
str += ' obj.' + p + ' = {};\r\n' ;
for ( const l of Object . values ( obj . exports [ p ] ) ) {
str += ' obj.' + p + '.' + l + ' = ' + obj . plugins [ p ] [ l ] . toString ( ) + '\r\n' ;
}
2019-10-09 01:22:01 -04:00
}
2019-10-10 14:13:25 -04:00
2019-11-13 16:31:29 -05:00
str += `
obj . callHook = function ( hookName , ... args ) {
for ( const p of Object . keys ( obj ) ) {
if ( typeof obj [ p ] [ hookName ] == 'function' ) {
2019-11-13 17:48:09 -05:00
obj [ p ] [ hookName ] . apply ( this , args ) ;
2019-10-10 14:13:25 -04:00
}
}
} ;
2019-11-13 16:31:29 -05:00
2019-10-10 14:13:25 -04:00
obj . registerPluginTab = function ( pluginRegInfo ) {
var d = pluginRegInfo ( ) ;
if ( ! Q ( d . tabId ) ) {
QA ( 'p19headers' , '<span onclick="return pluginHandler.callPluginPage(\\' '+d.tabId+' \ \ ');">' + d . tabTitle + '</span>' ) ;
}
} ;
obj . callPluginPage = function ( id ) {
var pages = Q ( 'p19pages' ) . querySelectorAll ( "#p19pages>div" ) ;
for ( const i of pages ) { i . style . display = 'none' ; }
QV ( id , true ) ;
} ;
2019-10-30 04:17:17 -04:00
obj . addPluginEx = function ( ) {
meshserver . send ( { action : 'addplugin' , url : Q ( 'pluginurlinput' ) . value } ) ;
} ;
obj . addPluginDlg = function ( ) {
2019-11-01 16:49:18 -04:00
setDialogMode ( 2 , "Plugin Config URL" , 3 , obj . addPluginEx , '<input type=text id=pluginurlinput style=width:100% />' ) ;
2019-10-30 04:17:17 -04:00
focusTextBox ( 'pluginurlinput' ) ;
} ;
2019-11-22 14:25:13 -05:00
obj . refreshPluginHandler = function ( ) {
let st = document . createElement ( 'script' ) ;
st . src = '/pluginHandler.js' ;
document . body . appendChild ( st ) ;
} ;
2019-10-10 14:13:25 -04:00
return obj ; } ; ` ;
return str ;
2019-10-08 04:18:40 -04:00
}
2019-11-22 14:25:13 -05:00
obj . refreshJS = function ( req , res ) {
// to minimize server reboots when installing new plugins, we call the new data and overwrite the old pluginHandler on the front end
res . set ( 'Content-Type' , 'text/javascript' ) ;
res . send ( 'pluginHandlerBuilder = ' + obj . prepExports ( ) + ' pluginHandler = new pluginHandlerBuilder();' ) ;
}
2019-10-10 14:13:25 -04:00
obj . callHook = function ( hookName , ... args ) {
for ( var p in obj . plugins ) {
if ( typeof obj . plugins [ p ] [ hookName ] == 'function' ) {
try {
obj . plugins [ p ] [ hookName ] ( args ) ;
} catch ( e ) {
console . log ( 'Error ocurred while running plugin hook' + p + ':' + hookName + ' (' + e + ')' ) ;
}
}
}
2019-10-08 04:18:40 -04:00
} ;
2019-10-10 14:13:25 -04:00
obj . addMeshCoreModules = function ( modulesAdd ) {
for ( var plugin in obj . plugins ) {
var moduleDirPath = null ;
var modulesDir = null ;
//if (obj.args.minifycore !== false) { try { moduleDirPath = obj.path.join(obj.pluginPath, 'modules_meshcore_min'); modulesDir = obj.fs.readdirSync(moduleDirPath); } catch (e) { } } // Favor minified modules if present.
if ( modulesDir == null ) { try { moduleDirPath = obj . path . join ( obj . pluginPath , plugin + '/modules_meshcore' ) ; modulesDir = obj . fs . readdirSync ( moduleDirPath ) ; } catch ( e ) { } } // Use non-minified mofules.
if ( modulesDir != null ) {
for ( var i in modulesDir ) {
if ( modulesDir [ i ] . toLowerCase ( ) . endsWith ( '.js' ) ) {
var moduleName = modulesDir [ i ] . substring ( 0 , modulesDir [ i ] . length - 3 ) ;
if ( moduleName . endsWith ( '.min' ) ) { moduleName = moduleName . substring ( 0 , moduleName . length - 4 ) ; } // Remove the ".min" for ".min.js" files.
var moduleData = [ 'try { addModule("' , moduleName , '", "' , obj . parent . escapeCodeString ( obj . fs . readFileSync ( obj . path . join ( moduleDirPath , modulesDir [ i ] ) ) . toString ( 'binary' ) ) , '"); addedModules.push("' , moduleName , '"); } catch (e) { }\r\n' ] ;
// Merge this module
// NOTE: "smbios" module makes some non-AI Linux segfault, only include for IA platforms.
if ( moduleName . startsWith ( 'amt-' ) || ( moduleName == 'smbios' ) ) {
// Add to IA / Intel AMT cores only
modulesAdd [ 'windows-amt' ] . push ( ... moduleData ) ;
modulesAdd [ 'linux-amt' ] . push ( ... moduleData ) ;
} else if ( moduleName . startsWith ( 'win-' ) ) {
// Add to Windows cores only
modulesAdd [ 'windows-amt' ] . push ( ... moduleData ) ;
} else if ( moduleName . startsWith ( 'linux-' ) ) {
// Add to Linux cores only
modulesAdd [ 'linux-amt' ] . push ( ... moduleData ) ;
modulesAdd [ 'linux-noamt' ] . push ( ... moduleData ) ;
} else {
// Add to all cores
modulesAdd [ 'windows-amt' ] . push ( ... moduleData ) ;
modulesAdd [ 'linux-amt' ] . push ( ... moduleData ) ;
modulesAdd [ 'linux-noamt' ] . push ( ... moduleData ) ;
}
// Merge this module to recovery modules if needed
if ( modulesAdd [ 'windows-recovery' ] != null ) {
if ( ( moduleName == 'win-console' ) || ( moduleName == 'win-message-pump' ) || ( moduleName == 'win-terminal' ) ) {
modulesAdd [ 'windows-recovery' ] . push ( ... moduleData ) ;
}
}
2019-10-08 04:18:40 -04:00
2019-10-10 14:13:25 -04:00
// Merge this module to agent recovery modules if needed
if ( modulesAdd [ 'windows-agentrecovery' ] != null ) {
if ( ( moduleName == 'win-console' ) || ( moduleName == 'win-message-pump' ) || ( moduleName == 'win-terminal' ) ) {
modulesAdd [ 'windows-agentrecovery' ] . push ( ... moduleData ) ;
}
}
}
}
2019-10-08 04:18:40 -04:00
}
2019-10-10 14:13:25 -04:00
}
2019-10-08 04:18:40 -04:00
} ;
2019-10-10 14:13:25 -04:00
obj . deviceViewPanel = function ( ) {
var panel = { } ;
for ( var p in obj . plugins ) {
if ( typeof obj . plugins [ p ] [ hookName ] == 'function' ) {
try {
panel [ p ] . header = obj . plugins [ p ] . on _device _header ( ) ;
panel [ p ] . content = obj . plugins [ p ] . on _device _page ( ) ;
} catch ( e ) {
console . log ( 'Error ocurred while getting plugin views ' + p + ':' + ' (' + e + ')' ) ;
}
}
}
return panel ;
2019-10-30 04:17:17 -04:00
} ;
obj . isValidConfig = function ( conf , url ) { // check for the required attributes
var isValid = true ;
if ( ! (
typeof conf . name == 'string'
2019-11-01 16:49:18 -04:00
&& typeof conf . shortName == 'string'
2019-10-30 04:17:17 -04:00
&& typeof conf . version == 'string'
2019-11-22 14:25:13 -05:00
// && typeof conf.author == 'string'
2019-10-30 04:17:17 -04:00
&& typeof conf . description == 'string'
&& typeof conf . hasAdminPanel == 'boolean'
&& typeof conf . homepage == 'string'
&& typeof conf . changelogUrl == 'string'
&& typeof conf . configUrl == 'string'
&& typeof conf . repository == 'object'
&& typeof conf . repository . type == 'string'
&& typeof conf . repository . url == 'string'
&& typeof conf . meshCentralCompat == 'string'
// && conf.configUrl == url // make sure we're loading a plugin from its desired config
) ) isValid = false ;
// more checks here?
2019-11-01 16:49:18 -04:00
if ( conf . repository . type == 'git' ) {
if ( typeof conf . downloadUrl != 'string' ) isValid = false ;
}
2019-10-30 04:17:17 -04:00
return isValid ;
} ;
2019-11-05 00:11:14 -05:00
obj . getPluginConfig = function ( configUrl ) {
return new Promise ( function ( resolve , reject ) {
2019-11-11 10:47:30 -05:00
if ( configUrl . indexOf ( 'https://' ) >= 0 ) {
var http = require ( 'https' ) ;
} else {
var http = require ( 'http' ) ;
}
2019-11-05 00:11:14 -05:00
if ( configUrl . indexOf ( '://' ) === - 1 ) reject ( 'Unable to fetch the config: Bad URL (' + configUrl + ')' ) ;
2019-11-11 10:47:30 -05:00
http . get ( configUrl , function ( res ) {
2019-11-05 00:11:14 -05:00
var configStr = '' ;
res . on ( 'data' , function ( chunk ) {
configStr += chunk ;
} ) ;
res . on ( 'end' , function ( ) {
if ( configStr [ 0 ] == '{' ) { // let's be sure we're JSON
try {
var pluginConfig = JSON . parse ( configStr ) ;
if ( Array . isArray ( pluginConfig ) && pluginConfig . length == 1 ) pluginConfig = pluginConfig [ 0 ] ;
if ( obj . isValidConfig ( pluginConfig , configUrl ) ) {
resolve ( pluginConfig ) ;
} else {
reject ( "This does not appear to be a valid plugin configuration." ) ;
}
} catch ( e ) { reject ( 'Error getting plugin config. Check that you have valid JSON.' ) ; }
} else {
reject ( 'Error getting plugin config. Check that you have valid JSON.' ) ;
}
} ) ;
} ) . on ( 'error' , function ( e ) {
reject ( "Error getting plugin config: " + e . message ) ;
} ) ;
} )
2019-11-01 16:49:18 -04:00
} ;
2019-11-05 00:11:14 -05:00
obj . getPluginLatest = function ( ) {
return new Promise ( function ( resolve , reject ) {
parent . db . getPlugins ( function ( err , plugins ) {
var proms = [ ] ;
plugins . forEach ( function ( curconf ) {
proms . push ( obj . getPluginConfig ( curconf . configUrl ) ) ;
} ) ;
var latestRet = [ ] ;
Promise . all ( proms ) . then ( function ( newconfs ) {
newconfs . forEach ( function ( newconf ) {
var curconf = null ;
plugins . forEach ( function ( conf ) {
if ( conf . configUrl == newconf . configUrl ) curconf = conf ;
} ) ;
if ( curconf == null ) reject ( 'Some plugin configs could not be parsed' ) ;
var s = require ( 'semver' ) ;
2019-11-06 20:00:09 -05:00
// MeshCentral doesn't adhere to semantic versioning (due to the -<alpha_char> at the end of the version)
// Convert the letter to ASCII for a "true" version number comparison
var mcCurVer = parent . currentVer . replace ( /-(.)$/ , ( m , p1 ) => { return p1 . charCodeAt ( 0 ) ; } ) ;
2019-11-24 16:36:12 -05:00
var piCompatVer = newconf . meshCentralCompat . replace ( /-(.)\b/g , ( m , p1 ) => { return p1 . charCodeAt ( 0 ) ; } ) ;
2019-11-05 00:11:14 -05:00
latestRet . push ( {
"id" : curconf . _id ,
"installedVersion" : curconf . version ,
"version" : newconf . version ,
"hasUpdate" : s . gt ( newconf . version , curconf . version ) ,
2019-11-06 20:00:09 -05:00
"meshCentralCompat" : s . satisfies ( mcCurVer , piCompatVer ) ,
2019-11-05 00:11:14 -05:00
"changelogUrl" : curconf . changelogUrl ,
"status" : curconf . status
} ) ;
resolve ( latestRet ) ;
} ) ;
} ) . catch ( ( e ) => { console . log ( 'Error reaching plugins, update call aborted. ' , e ) } ) ;
} ) ;
2019-11-01 16:49:18 -04:00
} ) ;
} ;
2019-11-05 00:11:14 -05:00
obj . addPlugin = function ( pluginConfig ) {
return new Promise ( function ( resolve , reject ) {
2019-11-01 16:49:18 -04:00
parent . db . addPlugin ( {
"name" : pluginConfig . name ,
"shortName" : pluginConfig . shortName ,
"version" : pluginConfig . version ,
"description" : pluginConfig . description ,
"hasAdminPanel" : pluginConfig . hasAdminPanel ,
"homepage" : pluginConfig . homepage ,
"changelogUrl" : pluginConfig . changelogUrl ,
"configUrl" : pluginConfig . configUrl ,
"downloadUrl" : pluginConfig . downloadUrl ,
"repository" : {
"type" : pluginConfig . repository . type ,
"url" : pluginConfig . repository . url
} ,
"meshCentralCompat" : pluginConfig . meshCentralCompat ,
2019-11-22 14:25:13 -05:00
"versionHistoryUrl" : pluginConfig . versionHistoryUrl ,
2019-11-01 16:49:18 -04:00
"status" : 0 // 0: disabled, 1: enabled
} , function ( ) {
2019-11-05 00:11:14 -05:00
parent . db . getPlugins ( function ( err , docs ) {
if ( err ) reject ( err ) ;
else resolve ( docs ) ;
} ) ;
} ) ;
} ) ;
2019-11-01 16:49:18 -04:00
} ;
2019-11-22 21:17:07 -05:00
obj . installPlugin = function ( id , version _only , force _url , func ) {
2019-11-01 16:49:18 -04:00
parent . db . getPlugin ( id , function ( err , docs ) {
// the "id" would probably suffice, but is probably an sanitary issue, generate a random instead
var randId = Math . random ( ) . toString ( 32 ) . replace ( '0.' , '' ) ;
var fileName = obj . parent . path . join ( require ( 'os' ) . tmpdir ( ) , 'Plugin_' + randId + '.zip' ) ;
var plugin = docs [ 0 ] ;
if ( plugin . repository . type == 'git' ) {
const file = obj . fs . createWriteStream ( fileName ) ;
2019-11-22 14:25:13 -05:00
var dl _url = plugin . downloadUrl ;
if ( version _only != null && version _only != false ) dl _url = version _only . url ;
2019-11-22 21:17:07 -05:00
if ( force _url != null ) dl _url = force _url ;
2019-11-22 14:25:13 -05:00
var url = require ( 'url' ) ;
var q = url . parse ( dl _url , true ) ;
var http = ( q . protocol == "http" ) ? require ( 'http' ) : require ( 'https' ) ;
var opts = {
path : q . pathname ,
host : q . hostname ,
port : q . port ,
headers : {
'User-Agent' : 'MeshCentral'
} ,
followRedirects : true ,
method : 'GET'
} ;
var request = http . get ( opts , function ( response ) {
// handle redirections with grace
2019-11-22 21:17:07 -05:00
if ( response . headers . location ) return obj . installPlugin ( id , version _only , response . headers . location , func ) ;
2019-11-01 16:49:18 -04:00
response . pipe ( file ) ;
file . on ( 'finish' , function ( ) {
file . close ( function ( ) {
var yauzl = require ( "yauzl" ) ;
if ( ! obj . fs . existsSync ( obj . pluginPath ) ) {
obj . fs . mkdirSync ( obj . pluginPath ) ;
}
if ( ! obj . fs . existsSync ( obj . parent . path . join ( obj . pluginPath , plugin . shortName ) ) ) {
obj . fs . mkdirSync ( obj . parent . path . join ( obj . pluginPath , plugin . shortName ) ) ;
}
yauzl . open ( fileName , { lazyEntries : true } , function ( err , zipfile ) {
if ( err ) throw err ;
zipfile . readEntry ( ) ;
zipfile . on ( "entry" , function ( entry ) {
let pluginPath = obj . parent . path . join ( obj . pluginPath , plugin . shortName ) ;
let pathReg = new RegExp ( /(.*?\/)/ ) ;
if ( process . platform == 'win32' ) pathReg = new RegExp ( /(.*?\\/ ) ;
let filePath = obj . parent . path . join ( pluginPath , entry . fileName . replace ( pathReg , '' ) ) ; // remove top level dir
if ( /\/$/ . test ( entry . fileName ) ) { // dir
if ( ! obj . fs . existsSync ( filePath ) )
obj . fs . mkdirSync ( filePath ) ;
zipfile . readEntry ( ) ;
} else { // file
zipfile . openReadStream ( entry , function ( err , readStream ) {
if ( err ) throw err ;
readStream . on ( "end" , function ( ) { zipfile . readEntry ( ) ; } ) ;
readStream . pipe ( obj . fs . createWriteStream ( filePath ) ) ;
} ) ;
}
} ) ;
2019-11-22 14:25:13 -05:00
zipfile . on ( "end" , function ( ) { setTimeout ( function ( ) {
2019-11-01 16:49:18 -04:00
obj . fs . unlinkSync ( fileName ) ;
2019-11-22 14:25:13 -05:00
if ( version _only == null || version _only === false ) {
2019-11-22 21:17:07 -05:00
parent . db . setPluginStatus ( id , 1 , func ) ;
2019-11-22 14:25:13 -05:00
} else {
2019-11-22 21:17:07 -05:00
parent . db . updatePlugin ( id , { status : 1 , version : version _only . name } , func ) ;
2019-11-22 14:25:13 -05:00
}
2019-11-01 16:49:18 -04:00
obj . plugins [ plugin . shortName ] = require ( obj . pluginPath + '/' + plugin . shortName + '/' + plugin . shortName + '.js' ) [ plugin . shortName ] ( obj ) ;
obj . exports [ plugin . shortName ] = obj . plugins [ plugin . shortName ] . exports ;
2019-11-22 14:25:13 -05:00
if ( typeof obj . plugins [ plugin . shortName ] . server _startup == 'function' ) obj . plugins [ plugin . shortName ] . server _startup ( ) ;
2019-11-22 21:17:07 -05:00
var plugin _config = obj . fs . readFileSync ( obj . pluginPath + '/' + plugin . shortName + '/config.json' ) ;
plugin _config = JSON . parse ( plugin _config ) ;
parent . db . updatePlugin ( plugin . _id , plugin _config ) ;
2019-11-22 14:25:13 -05:00
parent . updateMeshCore ( ) ;
2019-11-01 16:49:18 -04:00
} ) ; } ) ;
} ) ;
2019-10-30 04:17:17 -04:00
} ) ;
2019-11-01 16:49:18 -04:00
} ) ;
} ) ;
} else if ( plugin . repository . type == 'npm' ) {
2019-11-22 14:25:13 -05:00
// @TODO npm support? (need a test plugin)
2019-10-30 04:17:17 -04:00
}
2019-11-01 16:49:18 -04:00
} ) ;
} ;
2019-11-22 14:25:13 -05:00
obj . getPluginVersions = function ( id ) {
return new Promise ( function ( resolve , reject ) {
parent . db . getPlugin ( id , function ( err , docs ) {
var plugin = docs [ 0 ] ;
if ( plugin . versionHistoryUrl == null ) reject ( 'No version history available for this plugin.' ) ;
var url = require ( 'url' ) ;
var q = url . parse ( plugin . versionHistoryUrl , true ) ;
var http = ( q . protocol == "http" ) ? require ( 'http' ) : require ( 'https' ) ;
var opts = {
path : q . pathname ,
host : q . hostname ,
port : q . port ,
headers : {
'User-Agent' : 'MeshCentral' ,
'Accept' : 'application/vnd.github.v3+json'
}
} ;
http . get ( opts , function ( res ) {
var versStr = '' ;
res . on ( 'data' , function ( chunk ) {
versStr += chunk ;
} ) ;
res . on ( 'end' , function ( ) {
if ( versStr [ 0 ] == '{' || versStr [ 0 ] == '[' ) { // let's be sure we're JSON
try {
var vers = JSON . parse ( versStr ) ;
var vList = [ ] ;
var s = require ( 'semver' ) ;
vers . forEach ( ( v ) => {
if ( s . lt ( v . name , plugin . version ) ) vList . push ( v ) ;
} ) ;
if ( vers . length == 0 ) reject ( 'No previous versions available.' ) ;
resolve ( { 'id' : plugin . _id , 'name' : plugin . name , versionList : vList } ) ;
} catch ( e ) { reject ( 'Version history problem.' ) ; }
} else {
reject ( 'Version history appears to be malformed.' + versStr ) ;
}
} ) ;
} ) . on ( 'error' , function ( e ) {
reject ( "Error getting plugin versions: " + e . message ) ;
} ) ;
} ) ;
} ) ;
} ;
2019-11-01 16:49:18 -04:00
obj . disablePlugin = function ( id , func ) {
2019-11-22 14:25:13 -05:00
parent . db . getPlugin ( id , function ( err , docs ) {
var plugin = docs [ 0 ] ;
parent . db . setPluginStatus ( id , 0 , func ) ;
delete obj . plugins [ plugin . shortName ] ;
delete obj . exports [ plugin . shortName ] ;
} ) ;
2019-11-01 16:49:18 -04:00
} ;
obj . removePlugin = function ( id , func ) {
parent . db . getPlugin ( id , function ( err , docs ) {
var plugin = docs [ 0 ] ;
var rimraf = require ( "rimraf" ) ;
let pluginPath = obj . parent . path . join ( obj . pluginPath , plugin . shortName ) ;
rimraf . sync ( pluginPath ) ;
parent . db . deletePlugin ( id , func ) ;
delete obj . plugins [ plugin . shortName ] ;
obj . parent . updateMeshCore ( ) ;
2019-10-30 04:17:17 -04:00
} ) ;
} ;
2019-11-05 04:17:10 -05:00
obj . handleAdminReq = function ( req , res , user , serv ) {
2019-11-02 06:27:39 -04:00
var path = obj . path . join ( obj . pluginPath , req . query . pin , 'views' ) ;
serv . app . set ( 'views' , path ) ;
if ( obj . plugins [ req . query . pin ] != null && typeof obj . plugins [ req . query . pin ] . handleAdminReq == 'function' ) {
2019-11-05 04:17:10 -05:00
obj . plugins [ req . query . pin ] . handleAdminReq ( req , res , user ) ;
2019-11-02 06:27:39 -04:00
}
else {
res . sendStatus ( 401 ) ;
}
}
2019-11-05 04:17:10 -05:00
obj . handleAdminPostReq = function ( req , res , user , serv ) {
2019-11-02 06:27:39 -04:00
var path = obj . path . join ( obj . pluginPath , req . query . pin , 'views' ) ;
serv . app . set ( 'views' , path ) ;
if ( obj . plugins [ req . query . pin ] != null && typeof obj . plugins [ req . query . pin ] . handleAdminPostReq == 'function' ) {
2019-11-05 04:17:10 -05:00
obj . plugins [ req . query . pin ] . handleAdminPostReq ( req , res , user ) ;
2019-11-02 06:27:39 -04:00
}
else {
res . sendStatus ( 401 ) ;
}
}
2019-10-08 04:18:40 -04:00
return obj ;
} ;