From fa93dc1e0aeeee98dc2921a0b58865e19f72e9e9 Mon Sep 17 00:00:00 2001 From: Petr Balashov Date: Thu, 15 Jun 2017 19:15:23 +0200 Subject: [PATCH 01/16] added experimental encrypt/decrypt key shepherd api --- routes/shepherd.js | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/routes/shepherd.js b/routes/shepherd.js index f4e5daf..d3d394a 100644 --- a/routes/shepherd.js +++ b/routes/shepherd.js @@ -17,6 +17,7 @@ const electron = require('electron'), async = require('async'), rimraf = require('rimraf'), portscanner = require('portscanner'), + aes256 = require('nodejs-aes256'), Promise = require('bluebird'); const fixPath = require('fix-path'); @@ -137,6 +138,46 @@ shepherd.createIguanaDirs = function() { } } +shepherd.get('/encryptkey', function(req, res, next) { + if (req.query.ckey && + req.query.string) { + const encryptedKey = aes256.encrypt(req.query.ckey, req.query.string); + const successObj = { + 'msg': 'success', + 'result': encryptedKey + }; + + res.end(JSON.stringify(successObj)); + } else { + const errorObj = { + 'msg': 'error', + 'result': 'missing ckey or string to encrypt param' + }; + + res.end(JSON.stringify(errorObj)); + } +}); + +shepherd.get('/decryptkey', function(req, res, next) { + if (req.query.ckey && + req.query.string) { + const encryptedKey = aes256.decrypt(req.query.ckey, req.query.string); + const successObj = { + 'msg': 'success', + 'result': encryptedKey + }; + + res.end(JSON.stringify(successObj)); + } else { + const errorObj = { + 'msg': 'error', + 'result': 'missing ckey or string to encrypt param' + }; + + res.end(JSON.stringify(errorObj)); + } +}); + shepherd.get('/coinslist', function(req, res, next) { if (fs.existsSync(iguanaDir + '/shepherd/coinslist.json')) { fs.readFile(iguanaDir + '/shepherd/coinslist.json', 'utf8', function (err, data) { From af9f266787c66a5cf3c0cef6df14f116db22931e Mon Sep 17 00:00:00 2001 From: pbca26 Date: Fri, 23 Jun 2017 00:04:34 -0700 Subject: [PATCH 02/16] added pin strength --- package.json | 1 + routes/shepherd.js | 129 +++++++++++++++++++++++++++++++++++++-------- 2 files changed, 109 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index 5ec5300..5d93948 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "graceful-fs": "^4.1.11", "md5": "^2.2.1", "mkdirp": "^0.5.1", + "nodejs-aes256": "^1.0.1", "pm2": "^2.4.3", "portscanner": "^2.1.1", "ps-node": "^0.1.5", diff --git a/routes/shepherd.js b/routes/shepherd.js index c042a75..e5bc807 100644 --- a/routes/shepherd.js +++ b/routes/shepherd.js @@ -135,55 +135,134 @@ shepherd.createIguanaDirs = function() { if (!fs.existsSync(`${iguanaDir}/shepherd`)) { fs.mkdirSync(`${iguanaDir}/shepherd`); - if (fs.existsSync(iguanaDir)) { + if (fs.existsSync(`${iguanaDir}/shepherd`)) { console.log(`created shepherd folder at ${iguanaDir}/shepherd`); shepherd.writeLog(`create shepherd folder at ${iguanaDir}/shepherd`); } } else { - console.log('shepherd folder already exists'); + console.log('iguana/shepherd folder already exists'); + } + + if (!fs.existsSync(`${iguanaDir}/shepherd/pin`)) { + fs.mkdirSync(`${iguanaDir}/shepherd/pin`); + + if (fs.existsSync(`${iguanaDir}/shepherd/pin`)) { + console.log(`created pin folder at ${iguanaDir}/shepherd/pin`); + shepherd.writeLog(`create pin folder at ${iguanaDir}/shepherd/pin`); + } + } else { + console.log('shepherd/pin folder already exists'); } } shepherd.get('/encryptkey', function(req, res, next) { - if (req.query.ckey && - req.query.string) { - const encryptedKey = aes256.encrypt(req.query.ckey, req.query.string); - const successObj = { - 'msg': 'success', - 'result': encryptedKey - }; + if (req.query.key && + req.query.string && + req.query.pubkey) { + const encryptedString = aes256.encrypt(req.query.key, req.query.string); - res.end(JSON.stringify(successObj)); + // test pin security + // - at least 1 char in upper case + // - at least 1 digit + // - at least one special character + // - min length 8 + + const _pin = req.query.key; + const _pinTest = _pin.match('^(?=.*[A-Z])(?=.*[!@#$&*_])(?=.*[0-9])(?=.*[a-z]).{8}$'); + + console.log(_pinTest); + + fs.writeFile(`${iguanaDir}/shepherd/pin/${req.query.pubkey}.pin`, encryptedString, function (err) { + if (err) { + console.log('error writing pin file'); + } + + const returnObj = { + 'msg': 'success', + 'result': encryptedString + }; + + res.end(JSON.stringify(returnObj)); + }); } else { - const errorObj = { + let errorObj = { 'msg': 'error', - 'result': 'missing ckey or string to encrypt param' + 'result': '' }; + const _paramsList = [ + 'key', + 'string', + 'pubkey' + ]; + let _errorParamsList = []; + + for (let i = 0; i < _paramsList.length; i++) { + if (!req.query[_paramsList[i]]) { + _errorParamsList.push(_paramsList[i]); + } + } + errorObj.result = `missing param ${_errorParamsList.join(', ')}`; res.end(JSON.stringify(errorObj)); } }); shepherd.get('/decryptkey', function(req, res, next) { - if (req.query.ckey && - req.query.string) { - const encryptedKey = aes256.decrypt(req.query.ckey, req.query.string); - const successObj = { - 'msg': 'success', - 'result': encryptedKey - }; + if (req.query.key && + req.query.pubkey) { + if (fs.existsSync(`${iguanaDir}/shepherd/pin/${req.query.pubkey}.pin`)) { + fs.readFile(`${iguanaDir}/shepherd/pin/${req.query.pubkey}.pin`, 'utf8', function (err, data) { + if (err) { + const errorObj = { + 'msg': 'error', + 'result': err + }; - res.end(JSON.stringify(successObj)); + res.end(JSON.stringify(errorObj)); + } else { + const encryptedKey = aes256.decrypt(req.query.key, data); + // test if stored encrypted passphrase is decrypted correctly + // if not then the key is wrong + const _regexTest = encryptedKey.match(/^[0-9a-zA-Z ]+$/g); + let returnObj; + + if (!_regexTest) { + returnObj = { + 'msg': 'error', + 'result': 'wrong key' + }; + } else { + returnObj = { + 'msg': 'success', + 'result': encryptedKey + }; + } + + res.end(JSON.stringify(returnObj)); + } + }); + } else { + const errorObj = { + 'msg': 'error', + 'result': `file ${req.query.pubkey}.pin doesnt exist` + }; + + res.end(JSON.stringify(errorObj)); + } } else { const errorObj = { 'msg': 'error', - 'result': 'missing ckey or string to encrypt param' + 'result': 'missing key or pubkey param' }; res.end(JSON.stringify(errorObj)); } }); +/* + * type: GET + * params: none + */ shepherd.get('/coinslist', function(req, res, next) { if (fs.existsSync(`${iguanaDir}/shepherd/coinslist.json`)) { fs.readFile(`${iguanaDir}/shepherd/coinslist.json`, 'utf8', function (err, data) { @@ -251,6 +330,10 @@ shepherd.post('/guilog', function(req, res, next) { }); }); +/* + * type: GET + * params: type + */ shepherd.get('/getlog', function(req, res, next) { const logExt = req.query.type === 'txt' ? 'txt' : 'json'; @@ -282,6 +365,10 @@ shepherd.get('/getlog', function(req, res, next) { } }); +/* + * type: POST + * params: payload + */ shepherd.post('/coinslist', function(req, res, next) { const _payload = req.body.payload; From f02b29788e499a3a345b167e826afb19459a233b Mon Sep 17 00:00:00 2001 From: pbca26 Date: Fri, 30 Jun 2017 01:09:13 -0700 Subject: [PATCH 03/16] pin strength check extend special chars list --- routes/shepherd.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/routes/shepherd.js b/routes/shepherd.js index e5bc807..7967f17 100644 --- a/routes/shepherd.js +++ b/routes/shepherd.js @@ -155,7 +155,7 @@ shepherd.createIguanaDirs = function() { } } -shepherd.get('/encryptkey', function(req, res, next) { +shepherd.post('/encryptkey', function(req, res, next) { if (req.query.key && req.query.string && req.query.pubkey) { @@ -168,7 +168,7 @@ shepherd.get('/encryptkey', function(req, res, next) { // - min length 8 const _pin = req.query.key; - const _pinTest = _pin.match('^(?=.*[A-Z])(?=.*[!@#$&*_])(?=.*[0-9])(?=.*[a-z]).{8}$'); + const _pinTest = _pin.match('^(?=.*[A-Z])(?=.*[^<>{}\"/|;:.,~!?@#$%^=&*\\]\\\\()\\[_+]*$)(?=.*[0-9])(?=.*[a-z]).{8}$'); console.log(_pinTest); @@ -207,7 +207,7 @@ shepherd.get('/encryptkey', function(req, res, next) { } }); -shepherd.get('/decryptkey', function(req, res, next) { +shepherd.post('/decryptkey', function(req, res, next) { if (req.query.key && req.query.pubkey) { if (fs.existsSync(`${iguanaDir}/shepherd/pin/${req.query.pubkey}.pin`)) { From e80d977630fb75148f29338900cc2390c7e27e80 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Mon, 21 Aug 2017 11:55:43 +0300 Subject: [PATCH 04/16] return pin list --- gui/EasyDEX-GUI | 2 +- gui/app-closing.html | 1 - main.js | 14 +- make-patch.sh | 1 + routes/cache.js | 8 +- routes/shepherd.js | 524 +++++++++++++++++++++++-------------------- 6 files changed, 295 insertions(+), 255 deletions(-) diff --git a/gui/EasyDEX-GUI b/gui/EasyDEX-GUI index 7399c05..0092ac5 160000 --- a/gui/EasyDEX-GUI +++ b/gui/EasyDEX-GUI @@ -1 +1 @@ -Subproject commit 7399c05db6464596edf4c242f5a3a57445c70ded +Subproject commit 0092ac50871b6964e6462f3ba68ac7d1cd8c1421 diff --git a/gui/app-closing.html b/gui/app-closing.html index acbde0e..ec60212 100644 --- a/gui/app-closing.html +++ b/gui/app-closing.html @@ -20,6 +20,5 @@
App is closing. Please wait...
- \ No newline at end of file diff --git a/main.js b/main.js index 546e087..53606d0 100644 --- a/main.js +++ b/main.js @@ -153,7 +153,7 @@ guiapp.use(bodyParser.urlencoded({ extended: true, })); // support encoded bodies -guiapp.get('/', function (req, res) { +guiapp.get('/', function(req, res) { res.send('Agama app server'); }); @@ -251,7 +251,7 @@ function createLoadingWindow() { // loadingWindow.webContents.openDevTools() // if window closed we kill iguana proc - loadingWindow.on('hide', function () { + loadingWindow.on('hide', function() { // our app does not have multiwindow - so we dereference the window object instead of // putting them into an window_arr loadingWindow = null; @@ -486,7 +486,7 @@ function createWindow(status) { } } -app.on('window-all-closed', function () { +app.on('window-all-closed', function() { //if (os.platform() !== 'win32') { ig.kill(); } // in osx apps stay active in menu bar until explictly closed or quitted by CMD Q // so we do not kill the app --> for the case user clicks again on the iguana icon @@ -498,7 +498,7 @@ app.on('window-all-closed', function () { // Emitted before the application starts closing its windows. // Calling event.preventDefault() will prevent the default behaviour, which is terminating the application. -app.on('before-quit', function (event) { +app.on('before-quit', function(event) { console.log('before-quit'); if (mainWindow === null && loadingWindow != null) { // mainWindow not intitialised and loadingWindow not dereferenced // loading window is still open @@ -513,7 +513,7 @@ app.on('before-quit', function (event) { // Emitted when all windows have been closed and the application will quit. // Calling event.preventDefault() will prevent the default behaviour, which is terminating the application. -app.on('will-quit', function (event) { +app.on('will-quit', function(event) { if (mainWindow === null && loadingWindow != null) { // loading window is still open console.log('will-quit while loading window active'); @@ -523,14 +523,14 @@ app.on('will-quit', function (event) { // Emitted when the application is quitting. // Calling event.preventDefault() will prevent the default behaviour, which is terminating the application. -app.on('quit', function (event) { +app.on('quit', function(event) { if (mainWindow === null && loadingWindow != null) { console.log('quit while loading window active'); event.preventDefault(); } }) -app.on('activate', function () { +app.on('activate', function() { if (mainWindow === null) { // createWindow('open'); } diff --git a/make-patch.sh b/make-patch.sh index 978f7a8..25a98fa 100755 --- a/make-patch.sh +++ b/make-patch.sh @@ -17,6 +17,7 @@ mkdir patch/gui/EasyDEX-GUI/react cp -R gui/EasyDEX-GUI/react/build patch/gui/EasyDEX-GUI/react/build cp -R gui/EasyDEX-GUI/assets patch/gui/EasyDEX-GUI cp gui/index.html patch/gui/index.html +cp gui/app-closing.html patch/gui/app-closing.html cp ./main.js patch cp ./version patch cp -R routes patch/routes diff --git a/routes/cache.js b/routes/cache.js index 5631732..137e2a5 100644 --- a/routes/cache.js +++ b/routes/cache.js @@ -88,8 +88,8 @@ cache.get = function(req, res, next) { } } else { const errorObj = { - 'msg': 'error', - 'result': 'no pubkey provided', + msg: 'error', + result: 'no pubkey provided', }; res.end(JSON.stringify(errorObj)); @@ -376,7 +376,8 @@ cache.one = function(req, res, next) { } } - if (fs.existsSync(`${cache.iguanaDir}/shepherd/cache-${pubkey}.json`) && coin !== 'all') { + if (fs.existsSync(`${cache.iguanaDir}/shepherd/cache-${pubkey}.json`) && + coin !== 'all') { if (inMemCache) { console.log('cache one from mem'); outObj = inMemCache; @@ -457,6 +458,7 @@ cache.one = function(req, res, next) { async.forEachOf(_dexUrls, function(dexUrl, key) { var tooEarly = false; + if (outObj.basilisk[coin][address][key] && outObj.basilisk[coin][address][key].timestamp && (!skipTimeout && checkTimestamp(outObj.basilisk[coin][address][key].timestamp) < cacheGlobLifetime)) { diff --git a/routes/shepherd.js b/routes/shepherd.js index f6fe753..97b5a99 100644 --- a/routes/shepherd.js +++ b/routes/shepherd.js @@ -50,7 +50,8 @@ if (os.platform() === 'darwin') { komodoDir = `${process.env.HOME}/Library/Application Support/Komodo`, zcashdBin = '/Applications/ZCashSwingWalletUI.app/Contents/MacOS/zcashd', zcashcliBin = '/Applications/ZCashSwingWalletUI.app/Contents/MacOS/zcash-cli', - zcashDir = `${process.env.HOME}/Library/Application Support/ZcashParams`; + zcashDir = `${process.env.HOME}/Library/Application Support/Zcash`, + zcashParamsDir = `${process.env.HOME}/Library/Application Support/ZcashParams`; } if (os.platform() === 'linux') { @@ -60,8 +61,8 @@ if (os.platform() === 'linux') { iguanaIcon = path.join(__dirname, '/assets/icons/agama_icons/128x128.png'), komododBin = path.join(__dirname, '../assets/bin/linux64/komodod'), komodocliBin = path.join(__dirname, '../assets/bin/linux64/komodo-cli'), - komodoDir = `${process.env.HOME}/.komodo`; - zcashDir = `${process.env.HOME}/.zcash-params`; + komodoDir = `${process.env.HOME}/.komodo`, + zcashParamsDir = `${process.env.HOME}/.zcash-params`; } if (os.platform() === 'win32') { @@ -79,8 +80,8 @@ if (os.platform() === 'win32') { komodocliBin = path.normalize(komodocliBin), komodoDir = `${process.env.APPDATA}/Komodo`, komodoDir = path.normalize(komodoDir); - zcashDir = `${process.env.APPDATA}/ZcashParams`; - zcashDir = path.normalize(zcashDir); + zcashParamsDir = `${process.env.APPDATA}/ZcashParams`; + zcashParamsDir = path.normalize(zcashParamsDir); } shepherd.appConfig = { @@ -114,9 +115,9 @@ shepherd.defaultAppConfig = Object.assign({}, shepherd.appConfig); shepherd.coindInstanceRegistry = coindInstanceRegistry; shepherd.zcashParamsExist = function() { - if (fs.existsSync(zcashDir) && - fs.existsSync(`${zcashDir}/sprout-proving.key`) && - fs.existsSync(`${zcashDir}/sprout-verifying.key`)) { + if (fs.existsSync(zcashParamsDir) && + fs.existsSync(`${zcashParamsDir}/sprout-proving.key`) && + fs.existsSync(`${zcashParamsDir}/sprout-verifying.key`)) { console.log('zcashparams exist'); return true; } @@ -216,16 +217,16 @@ shepherd.get('/encryptkey', function(req, res, next) { } const returnObj = { - 'msg': 'success', - 'result': encryptedString + msg: 'success', + result: encryptedString, }; res.end(JSON.stringify(returnObj)); }); } else { let errorObj = { - 'msg': 'error', - 'result': '' + msg: 'error', + result: '', }; const _paramsList = [ 'key', @@ -252,8 +253,8 @@ shepherd.get('/decryptkey', function(req, res, next) { fs.readFile(`${iguanaDir}/shepherd/pin/${req.query.pubkey}.pin`, 'utf8', function (err, data) { if (err) { const errorObj = { - 'msg': 'error', - 'result': err + msg: 'error', + result: err, }; res.end(JSON.stringify(errorObj)); @@ -266,13 +267,13 @@ shepherd.get('/decryptkey', function(req, res, next) { if (!_regexTest) { returnObj = { - 'msg': 'error', - 'result': 'wrong key' + msg: 'error', + result: 'wrong key', }; } else { returnObj = { - 'msg': 'success', - 'result': encryptedKey + msg: 'success', + result: encryptedKey, }; } @@ -281,22 +282,58 @@ shepherd.get('/decryptkey', function(req, res, next) { }); } else { const errorObj = { - 'msg': 'error', - 'result': `file ${req.query.pubkey}.pin doesnt exist` + msg: 'error', + result: `file ${req.query.pubkey}.pin doesnt exist`, }; res.end(JSON.stringify(errorObj)); } } else { const errorObj = { - 'msg': 'error', - 'result': 'missing key or pubkey param' + msg: 'error', + result: 'missing key or pubkey param', }; res.end(JSON.stringify(errorObj)); } }); +shepherd.get('/getpinlist', function(req, res, next) { + if (fs.existsSync(`${iguanaDir}/shepherd/pin`)) { + fs.readdir(`${iguanaDir}/shepherd/pin`, function(err, items) { + let _pins = []; + + for (let i = 0; i < items.length; i++) { + if (items[i].substr(items[i].length - 4, 4) === '.pin') { + _pins.push(items[i].substr(0, items[i].length - 4)); + } + } + + if (!items.length) { + const errorObj = { + msg: 'error', + result: 'no pins', + }; + + res.end(JSON.stringify(errorObj)); + } else { + const successObj = { + msg: 'success', + result: _pins, + }; + + res.end(JSON.stringify(successObj)); + } + }); + } else { + const errorObj = { + msg: 'error', + result: 'pin folder doesnt exist', + }; + + res.end(JSON.stringify(errorObj)); + } +}); /** * Promise based download file method */ @@ -344,17 +381,17 @@ function downloadFile(configuration) { } const remoteBinLocation = { - 'win32': 'https://artifacts.supernet.org/latest/windows/', - 'darwin': 'https://artifacts.supernet.org/latest/osx/', - 'linux': 'https://artifacts.supernet.org/latest/linux/', + win32: 'https://artifacts.supernet.org/latest/windows/', + darwin: 'https://artifacts.supernet.org/latest/osx/', + linux: 'https://artifacts.supernet.org/latest/linux/', }; const localBinLocation = { - 'win32': 'assets/bin/win64/', - 'darwin': 'assets/bin/osx/', - 'linux': 'assets/bin/linux64/', + win32: 'assets/bin/win64/', + darwin: 'assets/bin/osx/', + linux: 'assets/bin/linux64/', }; const latestBins = { - 'win32': [ + win32: [ 'iguana.exe', 'komodo-cli.exe', 'komodod.exe', @@ -368,7 +405,7 @@ const latestBins = { 'nanomsg.dll', 'pthreadvc2.dll', ], - 'darwin': [ + darwin: [ 'iguana', 'komodo-cli', 'komodod', @@ -377,7 +414,7 @@ const latestBins = { 'libnanomsg.5.0.0.dylib', 'libstdc++.6.dylib', // encode %2B ], - 'linux': [ + linux: [ 'iguana', 'komodo-cli', 'komodod', @@ -394,8 +431,8 @@ let binsToUpdate = []; shepherd.get('/update/bins/check', function(req, res, next) { const rootLocation = path.join(__dirname, '../'); const successObj = { - 'msg': 'success', - 'result': 'bins', + msg: 'success', + result: 'bins', }; res.end(JSON.stringify(successObj)); @@ -530,15 +567,15 @@ shepherd.updateAgama = function() { const percentage = (received * 100) / total; if (Math.floor(percentage) % 5 === 0 || Math.floor(percentage) % 10 === 0) { - console.log('patch ' + percentage + '% | ' + received + ' bytes out of ' + total + ' bytes.'); + console.log(`patch ${percentage}% | ${received} bytes out of ${total} bytes.`); cache.io.emit('patch', { - 'msg': { - 'status': 'progress', - 'type': 'ui', - 'progress': percentage, - 'bytesTotal': total, - 'bytesReceived': received - } + msg: { + status: 'progress', + type: 'ui', + progress: percentage, + bytesTotal: total, + bytesReceived: received, + }, }); } } @@ -546,15 +583,15 @@ shepherd.updateAgama = function() { .then(function() { remoteFileSize('https://github.com/pbca26/dl-test/raw/master/patch.zip', function(err, remotePatchSize) { // verify that remote file is matching to DL'ed file - const localPatchSize = fs.statSync(rootLocation + 'patch.zip').size; + const localPatchSize = fs.statSync(`${rootLocation}patch.zip`).size; console.log('compare dl file size'); if (localPatchSize === remotePatchSize) { + const zip = new AdmZip(`${rootLocation}patch.zip`); + console.log('patch succesfully downloaded'); console.log('extracting contents'); - const zip = new AdmZip(rootLocation + 'patch.zip'); - if (shepherd.appConfig.dev) { if (!fs.existsSync(`${rootLocation}/patch`)) { fs.mkdirSync(`${rootLocation}/patch`); @@ -564,19 +601,19 @@ shepherd.updateAgama = function() { zip.extractAllTo(/*target path*/rootLocation + (shepherd.appConfig.dev ? '/patch' : ''), /*overwrite*/true); // TODO: extract files in chunks cache.io.emit('patch', { - 'msg': { - 'type': 'ui', - 'status': 'done' - } + msg: { + type: 'ui', + status: 'done', + }, }); - fs.unlink(rootLocation + 'patch.zip'); + fs.unlink(`${rootLocation}patch.zip`); } else { cache.io.emit('patch', { - 'msg': { - 'type': 'ui', - 'status': 'error', - 'message': 'size mismatch' - } + msg: { + type: 'ui', + status: 'error', + message: 'size mismatch', + }, }); console.log('patch file size doesnt match remote!'); } @@ -593,7 +630,7 @@ shepherd.get('/update/patch/check', function(req, res, next) { const rootLocation = path.join(__dirname, '../'); const options = { url: 'https://github.com/pbca26/dl-test/raw/master/version', - method: 'GET' + method: 'GET', }; request(options, function (error, response, body) { @@ -601,7 +638,7 @@ shepherd.get('/update/patch/check', function(req, res, next) { response.statusCode && response.statusCode === 200) { const remoteVersion = body.split('\n'); - const localVersionFile = fs.readFileSync(rootLocation + 'version', 'utf8'); + const localVersionFile = fs.readFileSync(`${rootLocation}version`, 'utf8'); let localVersion; if (localVersionFile.indexOf('\r\n') > -1) { @@ -612,26 +649,26 @@ shepherd.get('/update/patch/check', function(req, res, next) { if (remoteVersion[0] === localVersion[0]) { const successObj = { - 'msg': 'success', - 'result': 'latest' + msg: 'success', + result: 'latest', }; res.end(JSON.stringify(successObj)); } else { const successObj = { - 'msg': 'success', - 'result': 'update', - 'version': { - 'local': localVersion[0], - 'remote': remoteVersion[0], - } + msg: 'success', + result: 'update', + version: { + local: localVersion[0], + remote: remoteVersion[0], + }, }; res.end(JSON.stringify(successObj)); } } else { res.end({ - 'err': 'error getting update' + err: 'error getting update', }); } }); @@ -644,12 +681,12 @@ shepherd.get('/update/patch/check', function(req, res, next) { */ shepherd.get('/unpack', function(req, res, next) { const dlLocation = path.join(__dirname, '../'); - var zip = new AdmZip(dlLocation + 'patch.zip'); - zip.extractAllTo(/*target path*/dlLocation + '/patch/unpack', /*overwrite*/true); + const zip = new AdmZip(`${dlLocation}patch.zip`); + zip.extractAllTo(/*target path*/ `${dlLocation}/patch/unpack`, /*overwrite*/true); const successObj = { - 'msg': 'success', - 'result': 'unpack started' + msg: 'success', + result: 'unpack started', }; res.end(JSON.stringify(successObj)); @@ -664,15 +701,15 @@ shepherd.get('/coinslist', function(req, res, next) { fs.readFile(`${iguanaDir}/shepherd/coinslist.json`, 'utf8', function (err, data) { if (err) { const errorObj = { - 'msg': 'error', - 'result': err + msg: 'error', + result: err, }; res.end(JSON.stringify(errorObj)); } else { const successObj = { - 'msg': 'success', - 'result': data ? JSON.parse(data) : '' + msg: 'success', + result: data ? JSON.parse(data) : '', }; res.end(JSON.stringify(successObj)); @@ -680,8 +717,8 @@ shepherd.get('/coinslist', function(req, res, next) { }); } else { const errorObj = { - 'msg': 'error', - 'result': 'coin list doesn\'t exist' + msg: 'error', + result: 'coin list doesn\'t exist', }; res.end(JSON.stringify(errorObj)); @@ -704,11 +741,11 @@ shepherd.post('/guilog', function(req, res, next) { guiLog[shepherd.appSessionHash][req.body.timestamp].response = req.body.response; } else { guiLog[shepherd.appSessionHash][req.body.timestamp] = { - 'function': req.body.function, - 'type': req.body.type, - 'url': req.body.url, - 'payload': req.body.payload, - 'status': req.body.status, + function: req.body.function, + type: req.body.type, + url: req.body.url, + payload: req.body.payload, + status: req.body.status, }; } @@ -718,8 +755,8 @@ shepherd.post('/guilog', function(req, res, next) { } const returnObj = { - 'msg': 'success', - 'result': 'gui log entry is added' + msg: 'success', + result: 'gui log entry is added', }; res.end(JSON.stringify(returnObj)); @@ -737,15 +774,15 @@ shepherd.get('/getlog', function(req, res, next) { fs.readFile(`${iguanaDir}/shepherd/agamalog.${logExt}`, 'utf8', function (err, data) { if (err) { const errorObj = { - 'msg': 'error', - 'result': err + msg: 'error', + result: err, }; res.end(JSON.stringify(errorObj)); } else { const successObj = { - 'msg': 'success', - 'result': data ? JSON.parse(data) : '' + msg: 'success', + result: data ? JSON.parse(data) : '', }; res.end(JSON.stringify(successObj)); @@ -753,8 +790,8 @@ shepherd.get('/getlog', function(req, res, next) { }); } else { const errorObj = { - 'msg': 'error', - 'result': `agama.${logExt} doesnt exist` + msg: 'error', + result: `agama.${logExt} doesnt exist`, }; res.end(JSON.stringify(errorObj)); @@ -770,8 +807,8 @@ shepherd.post('/coinslist', function(req, res, next) { if (!_payload) { const errorObj = { - 'msg': 'error', - 'result': 'no payload provided' + msg: 'error', + result: 'no payload provided', }; res.end(JSON.stringify(errorObj)); @@ -779,15 +816,15 @@ shepherd.post('/coinslist', function(req, res, next) { fs.writeFile(`${cache.iguanaDir}/shepherd/coinslist.json`, JSON.stringify(_payload), function (err) { if (err) { const errorObj = { - 'msg': 'error', - 'result': err + msg: 'error', + result: err, }; res.end(JSON.stringify(errorObj)); } else { const successObj = { - 'msg': 'success', - 'result': 'done' + msg: 'success', + result: 'done', }; res.end(JSON.stringify(successObj)); @@ -839,7 +876,7 @@ shepherd.getConf = function(chain) { let parsedRpcConfig = { user: '', pass: '', - port: _port + port: _port, }; if (_match = _rpcConf.match(/rpcuser=\s*(.*)/)) { @@ -867,15 +904,15 @@ shepherd.getConf = function(chain) { shepherd.post('/cli', function(req, res, next) { if (!req.body.payload) { const errorObj = { - 'msg': 'error', - 'result': 'no payload provided' + msg: 'error', + result: 'no payload provided', }; res.end(JSON.stringify(errorObj)); } else if (!req.body.payload.cmd.match(/^[0-9a-zA-Z _\,\.\[\]"'/\\]+$/g)) { const errorObj = { - 'msg': 'error', - 'result': 'wrong cli string format' + msg: 'error', + result: 'wrong cli string format', }; res.end(JSON.stringify(errorObj)); @@ -891,15 +928,15 @@ shepherd.post('/cli', function(req, res, next) { if (_mode === 'default') { let _body = { - 'agent': 'bitcoinrpc', - 'method': _cmd + agent: 'bitcoinrpc', + method: _cmd, }; if (req.body.payload.params) { _body = { - 'agent': 'bitcoinrpc', - 'method': _cmd, - 'params': req.body.payload.params === ' ' ? [''] : req.body.payload.params + agent: 'bitcoinrpc', + method: _cmd, + params: req.body.payload.params === ' ' ? [''] : req.body.payload.params, }; } @@ -907,8 +944,8 @@ shepherd.post('/cli', function(req, res, next) { url: `http://localhost:${rpcConf[req.body.payload.chain].port}`, method: 'POST', auth: { - 'user': rpcConf[req.body.payload.chain].user, - 'pass': rpcConf[req.body.payload.chain].pass + user: rpcConf[req.body.payload.chain].user, + pass: rpcConf[req.body.payload.chain].pass, }, body: JSON.stringify(_body) }; @@ -937,13 +974,13 @@ shepherd.post('/cli', function(req, res, next) { if (stderr) { responseObj = { - 'msg': 'error', - 'result': stderr + msg: 'error', + result: stderr, }; } else { responseObj = { - 'msg': 'success', - 'result': stdout + msg: 'success', + result: stdout, }; } @@ -960,8 +997,8 @@ shepherd.post('/cli', function(req, res, next) { shepherd.post('/appconf', function(req, res, next) { if (!req.body.payload) { const errorObj = { - 'msg': 'error', - 'result': 'no payload provided' + msg: 'error', + result: 'no payload provided', }; res.end(JSON.stringify(errorObj)); @@ -969,8 +1006,8 @@ shepherd.post('/appconf', function(req, res, next) { shepherd.saveLocalAppConf(req.body.payload); const successObj = { - 'msg': 'success', - 'result': 'config saved' + msg: 'success', + result: 'config saved', }; res.end(JSON.stringify(successObj)); @@ -985,8 +1022,8 @@ shepherd.post('/appconf/reset', function(req, res, next) { shepherd.saveLocalAppConf(shepherd.defaultAppConfig); const successObj = { - 'msg': 'success', - 'result': 'config saved' + msg: 'success', + result: 'config saved', }; res.end(JSON.stringify(successObj)); @@ -1204,8 +1241,8 @@ shepherd.getSyncOnlyForksInfo = function() { */ shepherd.get('/forks/info/start', function(req, res, next) { const successObj = { - 'msg': 'success', - 'result': 'started' + msg: 'success', + result: 'started', }; res.end(JSON.stringify(successObj)); @@ -1218,8 +1255,8 @@ shepherd.get('/forks/info/start', function(req, res, next) { */ shepherd.get('/forks/info/show', function(req, res, next) { const successObj = { - 'msg': 'success', - 'result': JSON.stringify(syncOnlyIguanaInstanceInfo) + msg: 'success', + result: JSON.stringify(syncOnlyIguanaInstanceInfo), }; res.end(JSON.stringify(successObj)); @@ -1244,8 +1281,8 @@ shepherd.get('/forks/restart', function(req, res, next) { pm2.disconnect(); const successObj = { - 'msg': 'success', - 'result': 'restarted' + msg: 'success', + result: 'restarted', }; shepherd.writeLog(`iguana fork pmid ${_pmid} restarted`); @@ -1273,8 +1310,8 @@ shepherd.get('/forks/stop', function(req, res, next) { pm2.disconnect(); const successObj = { - 'msg': 'success', - 'result': 'stopped' + msg: 'success', + result: 'stopped', }; shepherd.writeLog(`iguana fork pmid ${_pmid} stopped`); @@ -1290,8 +1327,8 @@ shepherd.get('/forks/stop', function(req, res, next) { */ shepherd.get('/forks', function(req, res, next) { const successObj = { - 'msg': 'success', - 'result': iguanaInstanceRegistry + msg: 'success', + result: iguanaInstanceRegistry, }; res.end(JSON.stringify(successObj)); @@ -1302,9 +1339,9 @@ shepherd.get('/forks', function(req, res, next) { * params: name */ shepherd.post('/forks', function(req, res, next) { - const mode = req.body.mode, - coin = req.body.coin, - port = shepherd.appConfig.iguanaCorePort; + const mode = req.body.mode; + const coin = req.body.coin; + const port = shepherd.appConfig.iguanaCorePort; portscanner.findAPortNotInUse(port, port + 100, '127.0.0.1', function(error, _port) { pm2.connect(true, function(err) { //start up pm2 god @@ -1325,23 +1362,23 @@ shepherd.post('/forks', function(req, res, next) { }, function(err, apps) { if (apps && apps[0] && apps[0].process && apps[0].process.pid) { iguanaInstanceRegistry[_port] = { - 'mode': mode, - 'coin': coin, - 'pid': apps[0].process && apps[0].process.pid, - 'pmid': apps[0].pm2_env.pm_id + mode: mode, + coin: coin, + pid: apps[0].process && apps[0].process.pid, + pmid: apps[0].pm2_env.pm_id, }; cache.setVar('iguanaInstances', iguanaInstanceRegistry); const successObj = { - 'msg': 'success', - 'result': _port + msg: 'success', + result: _port, }; res.end(JSON.stringify(successObj)); } else { const errorObj = { - 'msg': 'success', - 'error': 'iguana start error' + msg: 'success', + error: 'iguana start error', }; res.end(JSON.stringify(errorObj)); @@ -1358,11 +1395,11 @@ shepherd.post('/forks', function(req, res, next) { } pm2.disconnect(); // Disconnect from PM2 - if (err) { - shepherd.writeLog(`iguana fork error: ${err}`); - console.log(`iguana fork error: ${err}`); - throw err; - } + if (err) { + shepherd.writeLog(`iguana fork error: ${err}`); + console.log(`iguana fork error: ${err}`); + throw err; + } }); }); }); @@ -1403,9 +1440,9 @@ shepherd.get('/InstantDEX/allcoins', function(req, res, next) { }); } else { successObj = { - 'native': nativeCoindList, - 'basilisk': [], - 'full': [] + native: nativeCoindList, + basilisk: [], + full: [], }; res.end(JSON.stringify(successObj)); @@ -1416,7 +1453,7 @@ shepherd.get('/InstantDEX/allcoins', function(req, res, next) { * type: GET * */ -shepherd.get('/SuperNET/activehandle', function(req, res, next) { +shepherd.get('/SuperNET/activehandle', function(req, res, next) { // not finished // TODO: if only native return obj // else query main iguana instance and return combined response // http://localhost:7778/api/SuperNET/activehandle?userpass=tmpIgRPCUser@1234 @@ -1440,11 +1477,11 @@ shepherd.get('/SuperNET/activehandle', function(req, res, next) { }); } else { successObj = { - 'pubkey': 'nativeonly', - 'result': 'success', - 'handle': '', - 'status': Object.keys(coindInstanceRegistry).length ? 'unlocked' : 'locked', - 'duration': 2507830 + pubkey: 'nativeonly', + result: 'success', + handle: '', + status: Object.keys(coindInstanceRegistry).length ? 'unlocked' : 'locked', + duration: 2507830, }; res.end(JSON.stringify(successObj)); @@ -1529,15 +1566,15 @@ shepherd.post('/debuglog', function(req, res) { shepherd.readDebugLog(`${_location}/debug.log`, _lastNLines) .then(function(result) { const _obj = { - 'msg': 'success', - 'result': result + msg: 'success', + result: result, }; res.end(JSON.stringify(_obj)); }, function(result) { const _obj = { - 'msg': 'error', - 'result': result + msg: 'error', + result: result, }; res.end(JSON.stringify(_obj)); @@ -1555,8 +1592,8 @@ shepherd.post('/herd', function(req, res) { herder(req.body.herd, req.body.options); const obj = { - 'msg': 'success', - 'result': 'result' + msg: 'success', + result: 'result', }; res.end(JSON.stringify(obj)); @@ -1570,9 +1607,9 @@ shepherd.post('/herd', function(req, res) { if (status === 'closed') { shepherd.writeLog(`komodod service start error at port ${_port}, reason: port is closed`); cache.io.emit('service', { - 'komodod': { - 'error': 'start error' - } + komodod: { + error: 'start error', + }, }); } }); @@ -1601,9 +1638,9 @@ shepherd.post('/herdlist', function(req, res) { shepherd.writeLog(list[0].pid); const obj = { - 'herdname': req.body.herdname, - 'status': list[0].pm2_env.status, - 'pid': list[0].pid + herdname: req.body.herdname, + status: list[0].pm2_env.status, + pid: list[0].pid, }; res.end(JSON.stringify(obj)); @@ -1620,8 +1657,8 @@ shepherd.post('/slay', function(req, res) { slayer(req.body.slay); const obj = { - 'msg': 'success', - 'result': 'result' + msg: 'success', + result: 'result', }; res.end(JSON.stringify(obj)); @@ -1643,8 +1680,8 @@ shepherd.post('/setconf', function(req, res) { } const obj = { - 'msg': 'success', - 'result': 'result' + msg: 'success', + result: 'result', }; res.end(JSON.stringify(obj)); @@ -1665,8 +1702,8 @@ shepherd.post('/getconf', function(req, res) { shepherd.writeLog(confpath); const obj = { - 'msg': 'success', - 'result': confpath + msg: 'success', + result: confpath, }; res.end(JSON.stringify(obj)); @@ -1682,8 +1719,8 @@ shepherd.get('/kick', function(req, res, next) { if (!_coin) { const errorObj = { - 'msg': 'error', - 'result': 'no coin name provided' + msg: 'error', + result: 'no coin name provided', }; res.end(JSON.stringify(errorObj)); @@ -1691,85 +1728,85 @@ shepherd.get('/kick', function(req, res, next) { if (!_type) { const errorObj = { - 'msg': 'error', - 'result': 'no type provided' + msg: 'error', + result: 'no type provided', }; res.end(JSON.stringify(errorObj)); } const kickStartDirs = { - 'soft': [ + soft: [ { - 'name': 'DB/[coin]', - 'type': 'pattern', - 'match': 'balancecrc.' + name: 'DB/[coin]', + type: 'pattern', + match: 'balancecrc.', }, { - 'name': 'DB/[coin]/utxoaddrs', - 'type': 'file' + name: 'DB/[coin]/utxoaddrs', + type: 'file', }, { - 'name': 'DB/[coin]/accounts', - 'type': 'folder' + name: 'DB/[coin]/accounts', + type: 'folder', }, { - 'name': 'DB/[coin]/fastfind', - 'type': 'folder' + name: 'DB/[coin]/fastfind', + type: 'folder', }, { - 'name': 'tmp/[coin]', - 'type': 'folder' + name: 'tmp/[coin]', + type: 'folder', } ], - 'hard': [ + hard: [ { - 'name': 'DB/[coin]', - 'type': 'pattern', - 'match': 'balancecrc.' + name: 'DB/[coin]', + type: 'pattern', + match: 'balancecrc.', }, { - 'name': 'DB/[coin]/utxoaddrs', - 'type': 'file' + name: 'DB/[coin]/utxoaddrs', + type: 'file', }, { - 'name': 'DB/[coin]', - 'type': 'pattern', - 'match': 'utxoaddrs.' + name: 'DB/[coin]', + type: 'pattern', + match: 'utxoaddrs.', }, { - 'name': 'DB/[coin]/accounts', - 'type': 'folder' + name: 'DB/[coin]/accounts', + type: 'folder', }, { - 'name': 'DB/[coin]/fastfind', - 'type': 'folder' + name: 'DB/[coin]/fastfind', + type: 'folder', }, { - 'name': 'DB/[coin]/spends', - 'type': 'folder' + name: 'DB/[coin]/spends', + type: 'folder', }, { - 'name': 'tmp/[coin]', - 'type': 'folder' + name: 'tmp/[coin]', + type: 'folder', } ], - 'brutal': [ // delete all coin related data + brutal: [ // delete all coin related data { - 'name': 'DB/[coin]', - 'type': 'folder' + name: 'DB/[coin]', + type: 'folder', }, { - 'name': 'DB/purgeable/[coin]', - 'type': 'folder' + name: 'DB/purgeable/[coin]', + type: 'folder', }, { - 'name': 'DB/ro/[coin]', - 'type': 'folder' + name: 'DB/ro/[coin]', + type: 'folder', }, { - 'name': 'tmp/[coin]', - 'type': 'folder' + name: 'tmp/[coin]', + type: 'folder', } ] }; @@ -1808,8 +1845,8 @@ shepherd.get('/kick', function(req, res, next) { } const successObj = { - 'msg': 'success', - 'result': 'kickstart: brutal is executed' + msg: 'success', + result: 'kickstart: brutal is executed', }; res.end(JSON.stringify(successObj)); @@ -1828,7 +1865,8 @@ shepherd.readDebugLog = function(fileLocation, lastNLines) { } else { console.log(`reading ${fileLocation}`); _fs.readFile(fileLocation, 'utf-8', function(err, data) { - if (err) throw err; + if (err) + throw err; const lines = data.trim().split('\n'); const lastLine = lines.slice(lines.length - lastNLines, lines.length).join('\n'); @@ -1906,10 +1944,10 @@ function herder(flock, data) { cwd: iguanaDir //set correct iguana directory }, function(err, apps) { iguanaInstanceRegistry[shepherd.appConfig.iguanaCorePort] = { - 'mode': 'main', - 'coin': 'none', - 'pid': apps[0].process.pid, - 'pmid': apps[0].pm2_env.pm_id + mode: 'main', + coin: 'none', + pid: apps[0].process.pid, + pmid: apps[0].pm2_env.pm_id, }; shepherd.writeLog(`iguana core started at port ${shepherd.appConfig.iguanaCorePort} pid ${apps[0].process.pid}`); @@ -1964,11 +2002,11 @@ function herder(flock, data) { if (status === 'closed') { // start komodod via exec const _customParamDict = { - 'silent': '&', - 'reindex': '-reindex', - 'change': '-pubkey=', - 'datadir': '-datadir=', - 'rescan': '-rescan' + silent: '&', + reindex: '-reindex', + change: '-pubkey=', + datadir: '-datadir=', + rescan: '-rescan', }; let _customParam = ''; @@ -1985,7 +2023,7 @@ function herder(flock, data) { const isChain = data.ac_name.match(/^[A-Z]*$/); const coindACParam = isChain ? ` -ac_name=${data.ac_name} ` : ''; - console.log('daemon param ' + data.ac_custom_param); + console.log(`daemon param ${data.ac_custom_param}`); coindInstanceRegistry[data.ac_name] = true; exec(`${komododBin} ${coindACParam}${data.ac_options.join(' ')}${_customParam}`, { @@ -2000,8 +2038,8 @@ function herder(flock, data) { if (error.toString().indexOf('using -reindex') > -1) { cache.io.emit('service', { - 'komodod': { - 'error': 'run -reindex' + komodod: { + error: 'run -reindex', } }); } @@ -2350,9 +2388,9 @@ function setConf(flock) { } function getConf(flock) { - let komodoDir = '', - ZcashDir = '', - DaemonConfPath = ''; + let komodoDir = ''; + let ZcashDir = ''; + let DaemonConfPath = ''; console.log(flock); shepherd.writeLog(`getconf flock: ${flock}`); @@ -2402,9 +2440,9 @@ function formatBytes(bytes, decimals) { if (bytes === 0) return '0 Bytes'; - const k = 1000, - dm = (decimals + 1) || 3, - sizes = [ + const k = 1000; + const dm = (decimals + 1) || 3; + const sizes = [ 'Bytes', 'KB', 'MB', @@ -2414,23 +2452,23 @@ function formatBytes(bytes, decimals) { 'EB', 'ZB', 'YB' - ], - i = Math.floor(Math.log(bytes) / Math.log(k)); + ]; + const i = Math.floor(Math.log(bytes) / Math.log(k)); return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`; } shepherd.SystemInfo = function() { const os_data = { - 'totalmem_bytes': os.totalmem(), - 'totalmem_readable': formatBytes(os.totalmem()), - 'arch': os.arch(), - 'cpu': os.cpus()[0].model, - 'cpu_cores': os.cpus().length, - 'platform': os.platform(), - 'os_release': os.release(), - 'os_type': os.type() - }; + 'totalmem_bytes': os.totalmem(), + 'totalmem_readable': formatBytes(os.totalmem()), + 'arch': os.arch(), + 'cpu': os.cpus()[0].model, + 'cpu_cores': os.cpus().length, + 'platform': os.platform(), + 'os_release': os.release(), + 'os_type': os.type() + }; return os_data; } From cc01c206843f54fb248e4185131648fa366d8720 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Mon, 21 Aug 2017 12:00:01 +0300 Subject: [PATCH 05/16] switched pin routes to post method --- routes/shepherd.js | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/routes/shepherd.js b/routes/shepherd.js index 97b5a99..b961d5c 100644 --- a/routes/shepherd.js +++ b/routes/shepherd.js @@ -194,11 +194,11 @@ shepherd.createIguanaDirs = function() { * type: POST * params: none */ -shepherd.get('/encryptkey', function(req, res, next) { - if (req.query.key && - req.query.string && - req.query.pubkey) { - const encryptedString = aes256.encrypt(req.query.key, req.query.string); +shepherd.post('/encryptkey', function(req, res, next) { + if (req.body.key && + req.body.string && + req.body.pubkey) { + const encryptedString = aes256.encrypt(req.body.key, req.body.string); // test pin security // - at least 1 char in upper case @@ -206,12 +206,12 @@ shepherd.get('/encryptkey', function(req, res, next) { // - at least one special character // - min length 8 - const _pin = req.query.key; + const _pin = req.body.key; const _pinTest = _pin.match('^(?=.*[A-Z])(?=.*[^<>{}\"/|;:.,~!?@#$%^=&*\\]\\\\()\\[_+]*$)(?=.*[0-9])(?=.*[a-z]).{8}$'); console.log(_pinTest); - fs.writeFile(`${iguanaDir}/shepherd/pin/${req.query.pubkey}.pin`, encryptedString, function (err) { + fs.writeFile(`${iguanaDir}/shepherd/pin/${req.body.pubkey}.pin`, encryptedString, function (err) { if (err) { console.log('error writing pin file'); } @@ -246,11 +246,11 @@ shepherd.get('/encryptkey', function(req, res, next) { } }); -shepherd.get('/decryptkey', function(req, res, next) { - if (req.query.key && - req.query.pubkey) { - if (fs.existsSync(`${iguanaDir}/shepherd/pin/${req.query.pubkey}.pin`)) { - fs.readFile(`${iguanaDir}/shepherd/pin/${req.query.pubkey}.pin`, 'utf8', function (err, data) { +shepherd.post('/decryptkey', function(req, res, next) { + if (req.body.key && + req.body.pubkey) { + if (fs.existsSync(`${iguanaDir}/shepherd/pin/${req.body.pubkey}.pin`)) { + fs.readFile(`${iguanaDir}/shepherd/pin/${req.body.pubkey}.pin`, 'utf8', function (err, data) { if (err) { const errorObj = { msg: 'error', @@ -259,7 +259,7 @@ shepherd.get('/decryptkey', function(req, res, next) { res.end(JSON.stringify(errorObj)); } else { - const encryptedKey = aes256.decrypt(req.query.key, data); + const encryptedKey = aes256.decrypt(req.body.key, data); // test if stored encrypted passphrase is decrypted correctly // if not then the key is wrong const _regexTest = encryptedKey.match(/^[0-9a-zA-Z ]+$/g); From 0a547687f9bfea249b0811e00800b059229e7ebf Mon Sep 17 00:00:00 2001 From: pbca26 Date: Mon, 21 Aug 2017 18:49:19 +0300 Subject: [PATCH 06/16] commented out support menu tab --- private/mainmenu.js | 12 ++++++------ routes/shepherd.js | 3 ++- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/private/mainmenu.js b/private/mainmenu.js index 07cbbdf..dd8780d 100644 --- a/private/mainmenu.js +++ b/private/mainmenu.js @@ -1,7 +1,7 @@ -const {Menu} = require('electron'), - electron = require('electron'), - app = electron.app, - {shell} = require('electron'); +const {Menu} = require('electron'); +const electron = require('electron'); +const app = electron.app; +const {shell} = require('electron'); const template = [ { @@ -86,7 +86,7 @@ const template = [ } ] }, - { + /*{ role: 'help', label: 'Support', submenu: [ @@ -121,7 +121,7 @@ const template = [ } } ] - } + }*/ ] if (process.platform === 'darwin') { diff --git a/routes/shepherd.js b/routes/shepherd.js index b961d5c..329ed40 100644 --- a/routes/shepherd.js +++ b/routes/shepherd.js @@ -20,7 +20,8 @@ const electron = require('electron'), aes256 = require('nodejs-aes256'), AdmZip = require('adm-zip'), remoteFileSize = require('remote-file-size'), - Promise = require('bluebird'); + Promise = require('bluebird'), + {shell} = require('electron'); const fixPath = require('fix-path'); var ps = require('ps-node'), From 7e2b84284ed4e7e21b5293e17fbb5c2fd8f44942 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Mon, 21 Aug 2017 19:04:38 +0300 Subject: [PATCH 07/16] mainWindow iguana icon location --- main.js | 1 + 1 file changed, 1 insertion(+) diff --git a/main.js b/main.js index 53606d0..49a80a2 100644 --- a/main.js +++ b/main.js @@ -341,6 +341,7 @@ function createWindow(status) { mainWindow.appSessionHash = appSessionHash; mainWindow.assetChainPorts = require('./routes/ports.js'); mainWindow.zcashParamsExist = shepherd.zcashParamsExist(); + mainWindow.iguanaIcon = iguanaIcon; if (appConfig.dev) { mainWindow.loadURL('http://127.0.0.1:3000'); From 67d1aa4e4f814713ef8837b60e7ee9d5c7f96fb0 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Wed, 23 Aug 2017 15:39:59 +0300 Subject: [PATCH 08/16] app settings schema --- main.js | 21 ++++---- routes/shepherd.js | 121 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 130 insertions(+), 12 deletions(-) diff --git a/main.js b/main.js index 49a80a2..7912a5b 100644 --- a/main.js +++ b/main.js @@ -337,6 +337,7 @@ function createWindow(status) { if (appConfig.v2) { shepherd.writeLog('show edex gui'); mainWindow.appConfig = appConfig; + mainWindow.appConfigSchema = shepherd.appConfigSchema; mainWindow.appBasicInfo = appBasicInfo; mainWindow.appSessionHash = appSessionHash; mainWindow.assetChainPorts = require('./routes/ports.js'); @@ -545,16 +546,16 @@ function formatBytes(bytes, decimals) { const k = 1000; const dm = decimals + 1 || 3; const sizes = [ - 'Bytes', - 'KB', - 'MB', - 'GB', - 'TB', - 'PB', - 'EB', - 'ZB', - 'YB' - ]; + 'Bytes', + 'KB', + 'MB', + 'GB', + 'TB', + 'PB', + 'EB', + 'ZB', + 'YB' + ]; const i = Math.floor(Math.log(bytes) / Math.log(k)); return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`; diff --git a/routes/shepherd.js b/routes/shepherd.js index 329ed40..7455036 100644 --- a/routes/shepherd.js +++ b/routes/shepherd.js @@ -96,7 +96,7 @@ shepherd.appConfig = { iguanaCorePort: 7778, maxDescriptors: { darwin: 90000, - linux: 1000000 + linux: 1000000, }, killIguanaOnStart: true, dev: false, @@ -105,12 +105,129 @@ shepherd.appConfig = { debug: false, cli: { passthru: true, - default: true + default: true, }, iguanaLessMode: true, roundValues: false, }; +shepherd.appConfigSchema = { + edexGuiOnly: { + display: false, + type: 'boolean', + displayName: 'EDEX GUI only', + }, + iguanaGuiOnly: { + display: false, + type: 'boolean', + displayName: 'Iguana GUI only', + }, + manualIguanaStart: { + display: false, + type: 'boolean', + displayName: 'Manual Iguana Start', + }, + skipBasiliskNetworkCheck: { + display: false, + type: 'boolean', + displayName: 'Skip Basilisk Network Check', + }, + minNotaries: { + display: false, + type: 'number', + displayName: 'Minimum notaries count', + info: 'Minimum number of notaries to connect to on startup', + }, + host: { + display: true, + type: 'string', + displayName: 'Hostname', + info: 'Application hostname', + }, + agamaPort: { + display: true, + type: 'number', + displayName: 'Agama Port', + info: 'Agama HTTP port. Required to run GUI.', + }, + iguanaCorePort: { + display: true, + type: 'number', + displayName: 'Iguana Core Port', + info: 'Default Iguana Core Port. Change it if you have conflicts with other applications.', + }, + maxDescriptors: { + display: false, + displayName: 'Max Descriptors per Process', + darwin: { + display: true, + displayName: 'MacOS (Darwin)', + type: 'number', + }, + linux: { + display: true, + displayName: 'Linux', + type: 'number', + }, + }, + killIguanaOnStart: { + display: true, + displayName: 'Kill Iguana Core Processes on Startup', + info: 'Kill any rogue Iguana Core processes during app startup', + type: 'boolean', + }, + dev: { + display: true, + displayName: 'Developer mode', + info: 'Enable developer mode.', + type: 'boolean', + }, + v2: { + display: false, + type: 'boolean', + }, + useBasiliskInstance: { + display: true, + displayName: 'Iguana Core Basilisk Instance', + info: 'Enable dedicated Iguana Core instance to handle all Basilisk network requests', + type: 'boolean', + }, + debug: { + display: true, + displayName: 'Debug', + info: 'Enable debug output', + type: 'boolean', + }, + cli: { + display: true, + displayName: 'Direct BitcoinRPC passthru interface', + info: 'Enable direct BitcoinRPC passthru interface. It will bypass Iguana Core and send requests directly to Bitcoin JSON server.', + passthru: { + display: true, + displayName: 'Enable Direct Passthru', + type: 'boolean', + }, + default: { + display: true, + displayName: 'Enable CLI passthru', + info: 'Enable komodo-cli passthru. This allows you to send CLI compatible commands directly from UI to komodo-cli.', + type: 'boolean', + }, + }, + iguanaLessMode: { + display: true, + displayName: 'Enable Native Only mode', + info: 'Limited to only Komodo native mode to speed up loading and reduce hardware resources consumption.', + type: 'boolean', + }, + roundValues: { + display: true, + displayName: 'Enable amount rounding', + info: 'Round \"dust\" amounts to save screen space.', + type: 'boolean', + }, +}; + shepherd.defaultAppConfig = Object.assign({}, shepherd.appConfig); shepherd.coindInstanceRegistry = coindInstanceRegistry; From 8e627b13d5b3621118aca76f98f84c9590c95b79 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Wed, 23 Aug 2017 16:42:03 +0300 Subject: [PATCH 09/16] move app config to a separate export --- routes/appConfig.js | 145 +++++++++++++++++++++++++++++++++++++++++++ routes/shepherd.js | 146 +------------------------------------------- 2 files changed, 148 insertions(+), 143 deletions(-) create mode 100644 routes/appConfig.js diff --git a/routes/appConfig.js b/routes/appConfig.js new file mode 100644 index 0000000..17c980c --- /dev/null +++ b/routes/appConfig.js @@ -0,0 +1,145 @@ +const appConfig = { + config: { + edexGuiOnly: true, + iguanaGuiOnly: false, + manualIguanaStart: false, + skipBasiliskNetworkCheck: true, + minNotaries: 8, + host: '127.0.0.1', + agamaPort: 17777, + iguanaCorePort: 7778, + maxDescriptors: { + darwin: 90000, + linux: 1000000, + }, + killIguanaOnStart: true, + dev: false, + v2: true, + useBasiliskInstance: true, + debug: false, + cli: { + passthru: true, + default: true, + }, + iguanaLessMode: true, + roundValues: false, + }, + schema: { + edexGuiOnly: { + display: false, + type: 'boolean', + displayName: 'EDEX GUI only', + }, + iguanaGuiOnly: { + display: false, + type: 'boolean', + displayName: 'Iguana GUI only', + }, + manualIguanaStart: { + display: false, + type: 'boolean', + displayName: 'Manual Iguana Start', + }, + skipBasiliskNetworkCheck: { + display: false, + type: 'boolean', + displayName: 'Skip Basilisk Network Check', + }, + minNotaries: { + display: false, + type: 'number', + displayName: 'Minimum notaries count', + info: 'Minimum number of notaries to connect to on startup', + }, + host: { + display: true, + type: 'string', + displayName: 'Hostname', + info: 'Application hostname', + }, + agamaPort: { + display: true, + type: 'number', + displayName: 'Agama Port', + info: 'Agama HTTP port. Required to run GUI.', + }, + iguanaCorePort: { + display: true, + type: 'number', + displayName: 'Iguana Core Port', + info: 'Default Iguana Core Port. Change it if you have conflicts with other applications.', + }, + maxDescriptors: { + display: false, + displayName: 'Max Descriptors per Process', + darwin: { + display: true, + displayName: 'MacOS (Darwin)', + type: 'number', + }, + linux: { + display: true, + displayName: 'Linux', + type: 'number', + }, + }, + killIguanaOnStart: { + display: true, + displayName: 'Kill Iguana Core Processes on Startup', + info: 'Kill any rogue Iguana Core processes during app startup', + type: 'boolean', + }, + dev: { + display: true, + displayName: 'Developer mode', + info: 'Enable developer mode.', + type: 'boolean', + }, + v2: { + display: false, + type: 'boolean', + }, + useBasiliskInstance: { + display: true, + displayName: 'Iguana Core Basilisk Instance', + info: 'Enable dedicated Iguana Core instance to handle all Basilisk network requests', + type: 'boolean', + }, + debug: { + display: true, + displayName: 'Debug', + info: 'Enable debug output', + type: 'boolean', + }, + cli: { + display: true, + displayName: 'Direct BitcoinRPC passthru interface', + info: 'Enable direct BitcoinRPC passthru interface. It will bypass Iguana Core and send requests directly to Bitcoin JSON server.', + passthru: { + display: true, + displayName: 'Enable Direct Passthru', + type: 'boolean', + }, + default: { + display: true, + displayName: 'Enable CLI passthru', + info: 'Enable komodo-cli passthru. This allows you to send CLI compatible commands directly from UI to komodo-cli.', + type: 'boolean', + }, + }, + iguanaLessMode: { + display: true, + displayName: 'Enable Native Only mode', + info: 'Limited to only Komodo native mode to speed up loading and reduce hardware resources consumption.', + type: 'boolean', + }, + roundValues: { + display: true, + displayName: 'Enable amount rounding', + info: 'Round \"dust\" amounts to save screen space.', + type: 'boolean', + }, + } +}; + +module.exports = appConfig; \ No newline at end of file diff --git a/routes/shepherd.js b/routes/shepherd.js index 7455036..7e55bd9 100644 --- a/routes/shepherd.js +++ b/routes/shepherd.js @@ -27,6 +27,7 @@ const fixPath = require('fix-path'); var ps = require('ps-node'), setconf = require('../private/setconf.js'), assetChainPorts = require('./ports.js'), + _appConfig = require('./appConfig.js'), shepherd = express.Router(), iguanaInstanceRegistry = {}, coindInstanceRegistry = {}, @@ -85,149 +86,8 @@ if (os.platform() === 'win32') { zcashParamsDir = path.normalize(zcashParamsDir); } -shepherd.appConfig = { - edexGuiOnly: true, - iguanaGuiOnly: false, - manualIguanaStart: false, - skipBasiliskNetworkCheck: true, - minNotaries: 8, - host: '127.0.0.1', - agamaPort: 17777, - iguanaCorePort: 7778, - maxDescriptors: { - darwin: 90000, - linux: 1000000, - }, - killIguanaOnStart: true, - dev: false, - v2: true, - useBasiliskInstance: true, - debug: false, - cli: { - passthru: true, - default: true, - }, - iguanaLessMode: true, - roundValues: false, -}; - -shepherd.appConfigSchema = { - edexGuiOnly: { - display: false, - type: 'boolean', - displayName: 'EDEX GUI only', - }, - iguanaGuiOnly: { - display: false, - type: 'boolean', - displayName: 'Iguana GUI only', - }, - manualIguanaStart: { - display: false, - type: 'boolean', - displayName: 'Manual Iguana Start', - }, - skipBasiliskNetworkCheck: { - display: false, - type: 'boolean', - displayName: 'Skip Basilisk Network Check', - }, - minNotaries: { - display: false, - type: 'number', - displayName: 'Minimum notaries count', - info: 'Minimum number of notaries to connect to on startup', - }, - host: { - display: true, - type: 'string', - displayName: 'Hostname', - info: 'Application hostname', - }, - agamaPort: { - display: true, - type: 'number', - displayName: 'Agama Port', - info: 'Agama HTTP port. Required to run GUI.', - }, - iguanaCorePort: { - display: true, - type: 'number', - displayName: 'Iguana Core Port', - info: 'Default Iguana Core Port. Change it if you have conflicts with other applications.', - }, - maxDescriptors: { - display: false, - displayName: 'Max Descriptors per Process', - darwin: { - display: true, - displayName: 'MacOS (Darwin)', - type: 'number', - }, - linux: { - display: true, - displayName: 'Linux', - type: 'number', - }, - }, - killIguanaOnStart: { - display: true, - displayName: 'Kill Iguana Core Processes on Startup', - info: 'Kill any rogue Iguana Core processes during app startup', - type: 'boolean', - }, - dev: { - display: true, - displayName: 'Developer mode', - info: 'Enable developer mode.', - type: 'boolean', - }, - v2: { - display: false, - type: 'boolean', - }, - useBasiliskInstance: { - display: true, - displayName: 'Iguana Core Basilisk Instance', - info: 'Enable dedicated Iguana Core instance to handle all Basilisk network requests', - type: 'boolean', - }, - debug: { - display: true, - displayName: 'Debug', - info: 'Enable debug output', - type: 'boolean', - }, - cli: { - display: true, - displayName: 'Direct BitcoinRPC passthru interface', - info: 'Enable direct BitcoinRPC passthru interface. It will bypass Iguana Core and send requests directly to Bitcoin JSON server.', - passthru: { - display: true, - displayName: 'Enable Direct Passthru', - type: 'boolean', - }, - default: { - display: true, - displayName: 'Enable CLI passthru', - info: 'Enable komodo-cli passthru. This allows you to send CLI compatible commands directly from UI to komodo-cli.', - type: 'boolean', - }, - }, - iguanaLessMode: { - display: true, - displayName: 'Enable Native Only mode', - info: 'Limited to only Komodo native mode to speed up loading and reduce hardware resources consumption.', - type: 'boolean', - }, - roundValues: { - display: true, - displayName: 'Enable amount rounding', - info: 'Round \"dust\" amounts to save screen space.', - type: 'boolean', - }, -}; - +shepherd.appConfig = _appConfig.config; +shepherd.appConfigSchema = _appConfig.schema; shepherd.defaultAppConfig = Object.assign({}, shepherd.appConfig); shepherd.coindInstanceRegistry = coindInstanceRegistry; From 05bec8bfb4e57bb982bd95dde9842e99470e29d6 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Wed, 23 Aug 2017 18:34:38 +0300 Subject: [PATCH 10/16] reject req if daemon port is taken --- routes/shepherd.js | 78 +++++++++++++++++++++++++++++----------------- 1 file changed, 50 insertions(+), 28 deletions(-) diff --git a/routes/shepherd.js b/routes/shepherd.js index 7e55bd9..2c293c2 100644 --- a/routes/shepherd.js +++ b/routes/shepherd.js @@ -107,7 +107,7 @@ shepherd.zcashParamsExist = function() { shepherd.readVersionFile = function() { // read app version const rootLocation = path.join(__dirname, '../'); - const localVersionFile = fs.readFileSync(rootLocation + 'version', 'utf8'); + const localVersionFile = fs.readFileSync(`${rootLocation}version`, 'utf8'); return localVersionFile; } @@ -187,8 +187,6 @@ shepherd.post('/encryptkey', function(req, res, next) { const _pin = req.body.key; const _pinTest = _pin.match('^(?=.*[A-Z])(?=.*[^<>{}\"/|;:.,~!?@#$%^=&*\\]\\\\()\\[_+]*$)(?=.*[0-9])(?=.*[a-z]).{8}$'); - console.log(_pinTest); - fs.writeFile(`${iguanaDir}/shepherd/pin/${req.body.pubkey}.pin`, encryptedString, function (err) { if (err) { console.log('error writing pin file'); @@ -1567,31 +1565,55 @@ shepherd.post('/herd', function(req, res) { console.log('======= req.body ======='); console.log(req.body); - herder(req.body.herd, req.body.options); + function testCoindPort() { + const _port = assetChainPorts[req.body.options.ac_name]; - const obj = { - msg: 'success', - result: 'result', - }; + portscanner.checkPortStatus(_port, '127.0.0.1', function(error, status) { + // Status is 'open' if currently in use or 'closed' if available + if (status === 'open') { + console.log(`komodod service start error at port ${_port}, reason: port is closed`); + shepherd.writeLog(`komodod service start error at port ${_port}, reason: port is closed`); + cache.io.emit('service', { + komodod: { + error: 'error starting ' + req.body.herd + ' ' + req.body.options.ac_name + ' daemon. Port ' + _port + ' is already taken!', + }, + }); - res.end(JSON.stringify(obj)); + const obj = { + msg: 'error', + result: 'error starting ' + req.body.herd + ' ' + req.body.options.ac_name + ' daemon. Port ' + _port + ' is already taken!', + }; + + res.status(500); + res.end(JSON.stringify(obj)); + } else { + herder(req.body.herd, req.body.options); + + const obj = { + msg: 'success', + result: 'result', + }; + + res.end(JSON.stringify(obj)); + } + }); + } if (req.body.herd === 'komodod') { - const _port = assetChainPorts[req.body.options.ac_name]; // check if komodod instance is already running + testCoindPort(); setTimeout(function() { - portscanner.checkPortStatus(_port, '127.0.0.1', function(error, status) { - // Status is 'open' if currently in use or 'closed' if available - if (status === 'closed') { - shepherd.writeLog(`komodod service start error at port ${_port}, reason: port is closed`); - cache.io.emit('service', { - komodod: { - error: 'start error', - }, - }); - } - }); + testCoindPort(); }, 10000); + } else { + herder(req.body.herd, req.body.options); + + const obj = { + msg: 'success', + result: 'result', + }; + + res.end(JSON.stringify(obj)); } }); @@ -1797,7 +1819,7 @@ shepherd.get('/kick', function(req, res, next) { console.log('deleting ' + currentKickItem.type + (currentKickItem.match ? ' ' + currentKickItem.match : '') + ' ' + iguanaDir + '/' + currentKickItem.name.replace('[coin]', _coin)); if (currentKickItem.type === 'folder' || currentKickItem.type === 'file') { - rimraf(iguanaDir + '/' + currentKickItem.name.replace('[coin]', _coin), function(err) { + rimraf(`${iguanaDir}/${currentKickItem.name.replace('[coin]', _coin)}`, function(err) { if (err) { throw err; } @@ -1919,7 +1941,7 @@ function herder(flock, data) { name: 'IGUANA', exec_mode : 'fork', args: [`-port=${shepherd.appConfig.iguanaCorePort}`], - cwd: iguanaDir //set correct iguana directory + cwd: iguanaDir // set correct iguana directory }, function(err, apps) { iguanaInstanceRegistry[shepherd.appConfig.iguanaCorePort] = { mode: 'main', @@ -1930,11 +1952,11 @@ function herder(flock, data) { shepherd.writeLog(`iguana core started at port ${shepherd.appConfig.iguanaCorePort} pid ${apps[0].process.pid}`); pm2.disconnect(); // Disconnect from PM2 - if (err) { - shepherd.writeLog(`iguana core port ${shepherd.appConfig.iguanaCorePort}`); - console.log(`iguana fork error: ${err}`); - throw err; - } + if (err) { + shepherd.writeLog(`iguana core port ${shepherd.appConfig.iguanaCorePort}`); + console.log(`iguana fork error: ${err}`); + throw err; + } }); }); } From e11869d641ba3fa6a8aedec07f3658f5b34748b7 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Wed, 23 Aug 2017 18:48:02 +0300 Subject: [PATCH 11/16] kill rogue komodo-cli during clean exit --- main.js | 41 ++--------------------------------------- routes/shepherd.js | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 39 deletions(-) diff --git a/main.js b/main.js index 7912a5b..2cdbaee 100644 --- a/main.js +++ b/main.js @@ -75,45 +75,8 @@ shepherd.writeLog(`app started in ${(appConfig.dev ? 'dev mode' : ' user mode')} shepherd.setConfKMD(); -// kill rogue iguana copies on start if (appConfig.killIguanaOnStart) { - let iguanaGrep; - - switch (osPlatform) { - case 'darwin': - iguanaGrep = "ps -p $(ps -A | grep -m1 iguana | awk '{print $1}') | grep -i iguana"; - break; - case 'linux': - iguanaGrep = 'ps -p $(pidof iguana) | grep -i iguana'; - break; - case 'win32': - iguanaGrep = 'tasklist'; - break; - } - - exec(iguanaGrep, function(error, stdout, stderr) { - if (stdout.indexOf('iguana') > -1) { - const pkillCmd = osPlatform === 'win32' ? 'taskkill /f /im iguana.exe' : 'pkill -15 iguana'; - - console.log('found another iguana process(es)'); - shepherd.writeLog('found another iguana process(es)'); - - exec(pkillCmd, function(error, stdout, stderr) { - console.log(`${pkillCmd} is issued`); - shepherd.writeLog(`${pkillCmd} is issued`); - - if (error !== null) { - console.log(`${pkillCmd} exec error: ${error}`); - shepherd.writeLog(`${pkillCmd} exec error: ${error}`); - }; - }); - } - - if (error !== null) { - console.log(`${iguanaGrep} exec error: ${error}`); - shepherd.writeLog(`${iguanaGrep} exec error: ${error}`); - }; - }); + shepherd.killRogueProcess('iguana'); } guiapp.use(function(req, res, next) { @@ -423,7 +386,7 @@ function createWindow(status) { shepherd.writeLog(result); resolve(result); - }, 2000) + }, 2000); }) } diff --git a/routes/shepherd.js b/routes/shepherd.js index 2c293c2..28b77d0 100644 --- a/routes/shepherd.js +++ b/routes/shepherd.js @@ -92,6 +92,48 @@ shepherd.defaultAppConfig = Object.assign({}, shepherd.appConfig); shepherd.coindInstanceRegistry = coindInstanceRegistry; +shepherd.killRogueProcess = function(processName) { + // kill rogue process copies on start + let processGrep; + const osPlatform = os.platform(); + + switch (osPlatform) { + case 'darwin': + processGrep = "ps -p $(ps -A | grep -m1 " + processName + " | awk '{print $1}') | grep -i " + processName; + break; + case 'linux': + processGrep = 'ps -p $(pidof ' + processName + ') | grep -i ' + processName; + break; + case 'win32': + processGrep = 'tasklist'; + break; + } + + exec(processGrep, function(error, stdout, stderr) { + if (stdout.indexOf(processName) > -1) { + const pkillCmd = osPlatform === 'win32' ? 'taskkill /f /im ' + processName + '.exe' : 'pkill -15 ' + processName; + + console.log('found another ' + processName + ' process(es)'); + shepherd.writeLog('found another ' + processName + ' process(es)'); + + exec(pkillCmd, function(error, stdout, stderr) { + console.log(`${pkillCmd} is issued`); + shepherd.writeLog(`${pkillCmd} is issued`); + + if (error !== null) { + console.log(`${pkillCmd} exec error: ${error}`); + shepherd.writeLog(`${pkillCmd} exec error: ${error}`); + }; + }); + } + + if (error !== null) { + console.log(`${processGrep} exec error: ${error}`); + shepherd.writeLog(`${processGrep} exec error: ${error}`); + }; + }); +} + shepherd.zcashParamsExist = function() { if (fs.existsSync(zcashParamsDir) && fs.existsSync(`${zcashParamsDir}/sprout-proving.key`) && @@ -819,6 +861,7 @@ shepherd.quitKomodod = function(timeout = 100) { const chain = key !== 'komodod' ? key : null; coindExitInterval[key] = setInterval(function() { + shepherd.killRogueProcess('komodo-cli'); console.log('exec ' + komodocliBin + (chain ? ' -ac_name=' + chain : '') + ' stop'); exec(komodocliBin + (chain ? ' -ac_name=' + chain : '') + ' stop', function(error, stdout, stderr) { console.log(`stdout: ${stdout}`); @@ -938,6 +981,7 @@ shepherd.post('/cli', function(req, res, next) { } }); } else { + shepherd.killRogueProcess('komodo-cli'); exec(komodocliBin + (_chain ? ' -ac_name=' + _chain : '') + ' ' + _cmd + _params, function(error, stdout, stderr) { console.log(`stdout: ${stdout}`); console.log(`stderr: ${stderr}`); From decec368896dff61e4c4afaa179a67a007c7d9c4 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Wed, 23 Aug 2017 21:02:36 +0300 Subject: [PATCH 12/16] switched zcashparams check fs to graceful-fs --- main.js | 3 ++- routes/shepherd.js | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/main.js b/main.js index 2cdbaee..6127e1f 100644 --- a/main.js +++ b/main.js @@ -131,6 +131,7 @@ let mainWindow; let loadingWindow; let appCloseWindow; let closeAppAfterLoading = false; +const _zcashParamsExist = shepherd.zcashParamsExist(); module.exports = guiapp; let iguanaIcon; @@ -304,7 +305,7 @@ function createWindow(status) { mainWindow.appBasicInfo = appBasicInfo; mainWindow.appSessionHash = appSessionHash; mainWindow.assetChainPorts = require('./routes/ports.js'); - mainWindow.zcashParamsExist = shepherd.zcashParamsExist(); + mainWindow.zcashParamsExist = _zcashParamsExist; mainWindow.iguanaIcon = iguanaIcon; if (appConfig.dev) { diff --git a/routes/shepherd.js b/routes/shepherd.js index 28b77d0..8cfc63d 100644 --- a/routes/shepherd.js +++ b/routes/shepherd.js @@ -135,9 +135,9 @@ shepherd.killRogueProcess = function(processName) { } shepherd.zcashParamsExist = function() { - if (fs.existsSync(zcashParamsDir) && - fs.existsSync(`${zcashParamsDir}/sprout-proving.key`) && - fs.existsSync(`${zcashParamsDir}/sprout-verifying.key`)) { + if (_fs.existsSync(zcashParamsDir) && + _fs.existsSync(`${zcashParamsDir}/sprout-proving.key`) && + _fs.existsSync(`${zcashParamsDir}/sprout-verifying.key`)) { console.log('zcashparams exist'); return true; } From 6969cd23bf50ef9d1a28ad406e38b37e03221d08 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Thu, 24 Aug 2017 17:36:46 +0300 Subject: [PATCH 13/16] komodo datadir param --- main.js | 1 + routes/appConfig.js | 9 ++++++- routes/shepherd.js | 58 ++++++++++++++++++++++++++++++++++++--------- 3 files changed, 56 insertions(+), 12 deletions(-) diff --git a/main.js b/main.js index 6127e1f..d798c4d 100644 --- a/main.js +++ b/main.js @@ -307,6 +307,7 @@ function createWindow(status) { mainWindow.assetChainPorts = require('./routes/ports.js'); mainWindow.zcashParamsExist = _zcashParamsExist; mainWindow.iguanaIcon = iguanaIcon; + mainWindow.testLocation = shepherd.testLocation; if (appConfig.dev) { mainWindow.loadURL('http://127.0.0.1:3000'); diff --git a/routes/appConfig.js b/routes/appConfig.js index 17c980c..b0f4422 100644 --- a/routes/appConfig.js +++ b/routes/appConfig.js @@ -23,6 +23,7 @@ const appConfig = { }, iguanaLessMode: true, roundValues: false, + dataDir: '', }, schema: { edexGuiOnly: { @@ -139,7 +140,13 @@ const appConfig = { info: 'Round \"dust\" amounts to save screen space.', type: 'boolean', }, - } + dataDir: { + display: true, + displayName: 'Komodo data directory', + info: 'The data directory is the location where Komodo data files are stored, including the wallet data file.', + type: 'folder', + }, + }, }; module.exports = appConfig; \ No newline at end of file diff --git a/routes/shepherd.js b/routes/shepherd.js index 8cfc63d..650356c 100644 --- a/routes/shepherd.js +++ b/routes/shepherd.js @@ -36,9 +36,10 @@ var ps = require('ps-node'), guiLog = {}, rpcConf = {}; +shepherd.appConfig = _appConfig.config; + // IGUANA FILES AND CONFIG SETTINGS -var iguanaConfsDirSrc = path.join(__dirname, '../assets/deps/confs'), - CorsProxyBin = path.join(__dirname, '../node_modules/corsproxy/bin/corsproxy'); +var iguanaConfsDirSrc = path.join(__dirname, '../assets/deps/confs'); // SETTING OS DIR TO RUN IGUANA FROM // SETTING APP ICON FOR LINUX AND WINDOWS @@ -49,7 +50,7 @@ if (os.platform() === 'darwin') { iguanaConfsDir = `${iguanaDir}/confs`, komododBin = path.join(__dirname, '../assets/bin/osx/komodod'), komodocliBin = path.join(__dirname, '../assets/bin/osx/komodo-cli'), - komodoDir = `${process.env.HOME}/Library/Application Support/Komodo`, + komodoDir = shepherd.appConfig.dataDir.length ? shepherd.appConfig.dataDir : `${process.env.HOME}/Library/Application Support/Komodo`, zcashdBin = '/Applications/ZCashSwingWalletUI.app/Contents/MacOS/zcashd', zcashcliBin = '/Applications/ZCashSwingWalletUI.app/Contents/MacOS/zcash-cli', zcashDir = `${process.env.HOME}/Library/Application Support/Zcash`, @@ -63,7 +64,7 @@ if (os.platform() === 'linux') { iguanaIcon = path.join(__dirname, '/assets/icons/agama_icons/128x128.png'), komododBin = path.join(__dirname, '../assets/bin/linux64/komodod'), komodocliBin = path.join(__dirname, '../assets/bin/linux64/komodo-cli'), - komodoDir = `${process.env.HOME}/.komodo`, + komodoDir = shepherd.appConfig.dataDir.length ? shepherd.appConfig.dataDir : `${process.env.HOME}/.komodo`, zcashParamsDir = `${process.env.HOME}/.zcash-params`; } @@ -80,18 +81,35 @@ if (os.platform() === 'win32') { komododBin = path.normalize(komododBin), komodocliBin = path.join(__dirname, '../assets/bin/win64/komodo-cli.exe'), komodocliBin = path.normalize(komodocliBin), - komodoDir = `${process.env.APPDATA}/Komodo`, + komodoDir = shepherd.appConfig.dataDir.length ? shepherd.appConfig.dataDir : `${process.env.APPDATA}/Komodo`, komodoDir = path.normalize(komodoDir); zcashParamsDir = `${process.env.APPDATA}/ZcashParams`; zcashParamsDir = path.normalize(zcashParamsDir); } -shepherd.appConfig = _appConfig.config; shepherd.appConfigSchema = _appConfig.schema; shepherd.defaultAppConfig = Object.assign({}, shepherd.appConfig); shepherd.coindInstanceRegistry = coindInstanceRegistry; +shepherd.testLocation = function(path) { + return new Promise(function(resolve, reject) { + fs.lstat(path, (err, stats) => { + if (err) { + console.log('error testing path ' + path); + resolve(-1); + } else { + if (stats.isDirectory()) { + resolve(true); + } else { + console.log('error testing path ' + path + ' not a folder'); + resolve(false); + } + } + }); + }); +} + shepherd.killRogueProcess = function(processName) { // kill rogue process copies on start let processGrep; @@ -113,8 +131,8 @@ shepherd.killRogueProcess = function(processName) { if (stdout.indexOf(processName) > -1) { const pkillCmd = osPlatform === 'win32' ? 'taskkill /f /im ' + processName + '.exe' : 'pkill -15 ' + processName; - console.log('found another ' + processName + ' process(es)'); - shepherd.writeLog('found another ' + processName + ' process(es)'); + console.log(`found another ${processName} process(es)`); + shepherd.writeLog(`found another ${processName} process(es)`); exec(pkillCmd, function(error, stdout, stderr) { console.log(`${pkillCmd} is issued`); @@ -367,7 +385,7 @@ function downloadFile(configuration) { agentOptions: { keepAlive: true, keepAliveMsecs: 15000, - } + }, }); let out = fs.createWriteStream(configuration.localFile); @@ -488,7 +506,7 @@ shepherd.get('/update/bins/check', function(req, res, next) { type: 'bins-check', status: 'done', fileList: binsToUpdate, - } + }, }); } }); @@ -508,7 +526,7 @@ shepherd.get('/update/bins', function(req, res, next) { result: { filesCount: binsToUpdate.length, list: binsToUpdate, - } + }, }; res.end(JSON.stringify(successObj)); @@ -1573,6 +1591,19 @@ shepherd.post('/debuglog', function(req, res) { let _lastNLines = req.body.lastLines; let _location; + if (os.platform() === 'darwin') { + komodoDir = shepherd.appConfig.dataDir.length ? shepherd.appConfig.dataDir : `${process.env.HOME}/Library/Application Support/Komodo`; + } + + if (os.platform() === 'linux') { + komodoDir = shepherd.appConfig.dataDir.length ? shepherd.appConfig.dataDir : `${process.env.HOME}/.komodo`; + } + + if (os.platform() === 'win32') { + komodoDir = shepherd.appConfig.dataDir.length ? shepherd.appConfig.dataDir : `${process.env.APPDATA}/Komodo`; + komodoDir = path.normalize(komodoDir); + } + if (_herd === 'iguana') { _location = iguanaDir; } else if (_herd === 'komodo') { @@ -1583,6 +1614,7 @@ shepherd.post('/debuglog', function(req, res) { _location = `${komodoDir}/${_ac}`; } + console.log('komodo dir ' + komodoDir); shepherd.readDebugLog(`${_location}/debug.log`, _lastNLines) .then(function(result) { const _obj = { @@ -2062,6 +2094,10 @@ function herder(flock, data) { _customParam = ` ${_customParamDict[data.ac_custom_param]}${data.ac_custom_param_value}`; } + if (shepherd.appConfig.dataDir.length) { + _customParam = _customParam + ' -datadir=' + shepherd.appConfig.dataDir + '/' + data.ac_name; + } + console.log(`exec ${komododBin} ${data.ac_options.join(' ')}${_customParam}`); shepherd.writeLog(`exec ${komododBin} ${data.ac_options.join(' ')}${_customParam}`); From 71879fe87088b122fed58d1adc5db8170c4aa09d Mon Sep 17 00:00:00 2001 From: pbca26 Date: Fri, 25 Aug 2017 17:27:58 +0300 Subject: [PATCH 14/16] fix bins perm on osx and linux --- main.js | 1 + routes/cache.js | 2 +- routes/shepherd.js | 26 ++++++++++++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/main.js b/main.js index d798c4d..055ea6b 100644 --- a/main.js +++ b/main.js @@ -54,6 +54,7 @@ const appBasicInfo = { app.setName(appBasicInfo.name); app.setVersion(appBasicInfo.version); +shepherd.binFixRights(); shepherd.createIguanaDirs(); const appSessionHash = md5(Date.now()); diff --git a/routes/cache.js b/routes/cache.js index 137e2a5..91379ae 100644 --- a/routes/cache.js +++ b/routes/cache.js @@ -306,7 +306,7 @@ cache.one = function(req, res, next) { let iguanaCorePort = req.query.port ? req.query.port : cache.appConfig.iguanaCorePort; let errorObj = { msg: 'error', - result: 'error' + result: 'error', }; let outObj = {}; const writeCache = function(timeStamp) { diff --git a/routes/shepherd.js b/routes/shepherd.js index 650356c..6cd9104 100644 --- a/routes/shepherd.js +++ b/routes/shepherd.js @@ -110,6 +110,32 @@ shepherd.testLocation = function(path) { }); } +// osx and linux +shepherd.binFixRights = function() { + const osPlatform = os.platform(); + const _bins = [ + iguanaBin, + komododBin, + komodocliBin + ]; + + if (osPlatform === 'darwin' || + osPlatform === 'linux') { + for (let i = 0; i < _bins.length; i++) { + _fs.stat(_bins[i], function(err, stat) { + if (!err) { + if (parseInt(stat.mode.toString(8), 10) !== 100775) { + console.log(`${_bins[i]} fix permissions`); + fsnode.chmodSync(_bins[i], '0775'); + } + } else { + console.log(`error: ${_bins[i]} not found`); + } + }); + } + } +} + shepherd.killRogueProcess = function(processName) { // kill rogue process copies on start let processGrep; From fc6d1c462f551db8f94b40e4245e32b37ad49487 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Fri, 25 Aug 2017 23:03:37 +0300 Subject: [PATCH 15/16] exec to execFile switch --- routes/shepherd.js | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/routes/shepherd.js b/routes/shepherd.js index 6cd9104..a2a6ec1 100644 --- a/routes/shepherd.js +++ b/routes/shepherd.js @@ -21,7 +21,8 @@ const electron = require('electron'), AdmZip = require('adm-zip'), remoteFileSize = require('remote-file-size'), Promise = require('bluebird'), - {shell} = require('electron'); + {shell} = require('electron'), + { execFile } = require('child_process'); const fixPath = require('fix-path'); var ps = require('ps-node'), @@ -906,8 +907,12 @@ shepherd.quitKomodod = function(timeout = 100) { coindExitInterval[key] = setInterval(function() { shepherd.killRogueProcess('komodo-cli'); - console.log('exec ' + komodocliBin + (chain ? ' -ac_name=' + chain : '') + ' stop'); - exec(komodocliBin + (chain ? ' -ac_name=' + chain : '') + ' stop', function(error, stdout, stderr) { + let _arg = []; + if (chain) { + _arg.push(`-ac_name=${chain}`); + } + _arg.push('stop'); + execFile(`${komodocliBin}`, _arg, function(error, stdout, stderr) { console.log(`stdout: ${stdout}`); console.log(`stderr: ${stderr}`); @@ -1026,7 +1031,9 @@ shepherd.post('/cli', function(req, res, next) { }); } else { shepherd.killRogueProcess('komodo-cli'); - exec(komodocliBin + (_chain ? ' -ac_name=' + _chain : '') + ' ' + _cmd + _params, function(error, stdout, stderr) { + let _arg = (_chain ? ' -ac_name=' + _chain : '') + ' ' + _cmd + _params; + _arg = _arg.trim().split(' '); + execFile(komodocliBin, _arg, function(error, stdout, stderr) { console.log(`stdout: ${stdout}`); console.log(`stderr: ${stderr}`); @@ -2132,7 +2139,9 @@ function herder(flock, data) { console.log(`daemon param ${data.ac_custom_param}`); coindInstanceRegistry[data.ac_name] = true; - exec(`${komododBin} ${coindACParam}${data.ac_options.join(' ')}${_customParam}`, { + let _arg = `${coindACParam}${data.ac_options.join(' ')}${_customParam}`; + _arg = _arg.trim().split(' '); + execFile(`${komododBin}`, _arg, { maxBuffer: 1024 * 10000 // 10 mb }, function(error, stdout, stderr) { shepherd.writeLog(`stdout: ${stdout}`); @@ -2549,16 +2558,16 @@ function formatBytes(bytes, decimals) { const k = 1000; const dm = (decimals + 1) || 3; const sizes = [ - 'Bytes', - 'KB', - 'MB', - 'GB', - 'TB', - 'PB', - 'EB', - 'ZB', - 'YB' - ]; + 'Bytes', + 'KB', + 'MB', + 'GB', + 'TB', + 'PB', + 'EB', + 'ZB', + 'YB' + ]; const i = Math.floor(Math.log(bytes) / Math.log(k)); return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`; From cfaa2d337aeea7cc85254a4e938557c670fad936 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Sat, 26 Aug 2017 03:59:17 -0700 Subject: [PATCH 16/16] cli passphru fix --- routes/shepherd.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/routes/shepherd.js b/routes/shepherd.js index a2a6ec1..1bbed1f 100644 --- a/routes/shepherd.js +++ b/routes/shepherd.js @@ -906,7 +906,6 @@ shepherd.quitKomodod = function(timeout = 100) { const chain = key !== 'komodod' ? key : null; coindExitInterval[key] = setInterval(function() { - shepherd.killRogueProcess('komodo-cli'); let _arg = []; if (chain) { _arg.push(`-ac_name=${chain}`); @@ -918,6 +917,7 @@ shepherd.quitKomodod = function(timeout = 100) { if (stdout.indexOf('EOF reached') > -1 || stderr.indexOf('EOF reached') > -1 || + (error && error.toString().indexOf('Command failed') > -1 && !stderr) || // win "special snowflake" case stdout.indexOf('connect to server: unknown (code -1)') > -1 || stderr.indexOf('connect to server: unknown (code -1)') > -1) { delete coindInstanceRegistry[key]; @@ -927,6 +927,7 @@ shepherd.quitKomodod = function(timeout = 100) { if (error !== null) { console.log(`exec error: ${error}`); } + shepherd.killRogueProcess('komodo-cli'); }); }, timeout); } @@ -1030,7 +1031,6 @@ shepherd.post('/cli', function(req, res, next) { } }); } else { - shepherd.killRogueProcess('komodo-cli'); let _arg = (_chain ? ' -ac_name=' + _chain : '') + ' ' + _cmd + _params; _arg = _arg.trim().split(' '); execFile(komodocliBin, _arg, function(error, stdout, stderr) { @@ -1056,6 +1056,7 @@ shepherd.post('/cli', function(req, res, next) { } res.end(JSON.stringify(responseObj)); + shepherd.killRogueProcess('komodo-cli'); }); } }