From f473b16d72902c72dd350eb35c58861ff66aa66e Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Mon, 11 Jun 2018 09:16:22 +0200 Subject: [PATCH] Exchange API Keys at web server only --- CloudVM/CloudVM.js | 13 +++- CloudVM/PoloniexAPIClient.js | 23 +++---- Dashboard.js | 1 + Ecosystem.js | 7 --- Server/Permissions.js | 19 ++---- SplashScreen.js | 4 +- server.js | 115 +++++++++++++++++++++-------------- 7 files changed, 97 insertions(+), 85 deletions(-) diff --git a/CloudVM/CloudVM.js b/CloudVM/CloudVM.js index 48c919119..f5cb0c148 100644 --- a/CloudVM/CloudVM.js +++ b/CloudVM/CloudVM.js @@ -31,7 +31,18 @@ function newCloudVM() { window.CURRENT_ENVIRONMENT = "Develop"; window.CURRENT_EXECUTION_AT = "Browser"; window.STORAGE_PERMISSIONS = ecosystem.getStoragePermissions(); - window.EXCHANGE_KEYS = ecosystem.getExchangeKeys(); + + /* + When running at the browser, the AACloud VM will look for this data, in this case it does not contain any key or secret, since the browser only know the + session token the user received when he logged in. + */ + + window.EXCHANGE_KEYS = { + Poloniex: { + Key: "", + Secret: "" + } + } root.initialize(pUI_COMMANDS, onInitialized); diff --git a/CloudVM/PoloniexAPIClient.js b/CloudVM/PoloniexAPIClient.js index d86c7f6a0..6b33e0267 100644 --- a/CloudVM/PoloniexAPIClient.js +++ b/CloudVM/PoloniexAPIClient.js @@ -1,10 +1,9 @@ -function newPoloniexAPIClient(pKey, pSecret) { +function newPoloniexAPIClient() { const INFO_LOG = true; const LOG_FILE_CONTENT = false; - let key = pKey; - let secret = pSecret; + window.SESSION_TOKEN = window.localStorage.getItem("sessionToken"); let thisObject = { API: { @@ -81,8 +80,7 @@ let path = "PoloniexAPIClient" + "/" + "returnOpenOrders" + "/" - + key + "/" - + secret + "/" + + window.SESSION_TOKEN + "/" + pMarketAssetA + "/" + pMarketAssetB ; @@ -101,8 +99,7 @@ let path = "PoloniexAPIClient" + "/" + "returnOrderTrades" + "/" - + key + "/" - + secret + "/" + + window.SESSION_TOKEN + "/" + pPositionId ; @@ -120,8 +117,7 @@ let path = "PoloniexAPIClient" + "/" + "buy" + "/" - + key + "/" - + secret + "/" + + window.SESSION_TOKEN + "/" + pMarketAssetA + "/" + pMarketAssetB + "/" + pRate + "/" @@ -142,8 +138,7 @@ let path = "PoloniexAPIClient" + "/" + "sell" + "/" - + key + "/" - + secret + "/" + + window.SESSION_TOKEN + "/" + pMarketAssetA + "/" + pMarketAssetB + "/" + pRate + "/" @@ -164,8 +159,7 @@ let path = "PoloniexAPIClient" + "/" + "moveOrder" + "/" - + key + "/" - + secret + "/" + + window.SESSION_TOKEN + "/" + pPositionId + "/" + pNewRate + "/" + pPositionAmountB @@ -185,8 +179,7 @@ let path = "PoloniexAPIClient" + "/" + "returnTicker" + "/" - + key + "/" - + secret + + window.SESSION_TOKEN ; callServer(undefined, path + "/NO-LOG", onServerResponse); diff --git a/Dashboard.js b/Dashboard.js index 699685762..5d378d686 100644 --- a/Dashboard.js +++ b/Dashboard.js @@ -129,6 +129,7 @@ function convertTimePeriodToName(pTimePeriod) { } } + let cloudVM = newCloudVM(); window.AT_BREAKPOINT = false; diff --git a/Ecosystem.js b/Ecosystem.js index 19e8eaaba..3685fd45a 100644 --- a/Ecosystem.js +++ b/Ecosystem.js @@ -13,7 +13,6 @@ function newEcosystem() { getPlotter: getPlotter, getPlotterModule: getPlotterModule, getStoragePermissions: getStoragePermissions, - getExchangeKeys: getExchangeKeys, initialize: initialize } @@ -32,12 +31,6 @@ function newEcosystem() { } - function getExchangeKeys() { - - return ECOSYSTEM.EXCHANGE_KEYS; - - } - function getHost(pHostCodeName) { for (let i = 0; i < ECOSYSTEM.hosts.length; i++) { diff --git a/Server/Permissions.js b/Server/Permissions.js index c7c0c2e25..d9c18ef55 100644 --- a/Server/Permissions.js +++ b/Server/Permissions.js @@ -19,7 +19,7 @@ filePath = '../' + 'Connection-Strings' + '/' + 'Storage.Permissions.json'; pEcosystemObject.STORAGE_PERMISSIONS = JSON.parse(fs.readFileSync(filePath, 'utf8')); - readExchangeAPIKey(); + readPermissions(); } catch (err) { console.log("[ERROR] readStoragePermissions -> err = " + err.message); @@ -27,26 +27,19 @@ } } - function readExchangeAPIKey() { + function readPermissions() { try { let fs = require('fs'); - let filePath = '../' + 'Exchange-Keys' + '/' + 'Secret.Keys' + '.json'; + let filePath = '../' + 'Permissions' + '/' + 'Secrets' + '.json'; - pEcosystemObject.EXCHANGE_KEYS = JSON.parse(fs.readFileSync(filePath, 'utf8')); - callBackFunction(); + let permissioins = JSON.parse(fs.readFileSync(filePath, 'utf8')); + callBackFunction(permissioins); } catch (err) { - console.log("[ERROR] readExchangeAPIKey -> err = " + err.message); + console.log("[ERROR] readPermissions -> err = " + err.message); console.log("[HINT] You need to have a file at this path -> " + filePath); - pEcosystemObject.EXCHANGE_KEYS = { - Poloniex: { - Key: "", - Secret: "" - } - } - callBackFunction(); } } diff --git a/SplashScreen.js b/SplashScreen.js index 80b65a9a5..34d7cc650 100644 --- a/SplashScreen.js +++ b/SplashScreen.js @@ -67,8 +67,6 @@ function newSplashScreen() { opacity = opacity - 0.05; } - if (canDrawLogo === false) { return; } - thisObject.container.frame.draw(false, false); /* Set the background. */ @@ -82,6 +80,8 @@ function newSplashScreen() { browserCanvasContext.fill(); + if (canDrawLogo === false) { return; } + /* First the AA Logo. */ let imageHeight = 96; diff --git a/server.js b/server.js index 5adf0caf0..59cd0c015 100644 --- a/server.js +++ b/server.js @@ -49,6 +49,8 @@ let isHttpServerStarted = false; const STORAGE = require('./Server/Storage'); let storage = STORAGE.newStorage(); +let authenticatedSession; // We do not send these keys to the browser, instead they are kept here for when they are needed. + initialize(); function initialize() { @@ -93,7 +95,9 @@ function initialize() { permissions.initialize(ecosystemObject, onInitialized); - function onInitialized() { + function onInitialized(pPermissionsSecrets) { + + authenticatedSession = pPermissionsSecrets; const BOT_SCRIPTS = require('./Server/BotsScripts'); botScripts = BOT_SCRIPTS.newBotScripts(); @@ -575,55 +579,72 @@ function onBrowserRequest(request, response) { case "PoloniexAPIClient": // This is trying to access this library functionality from the broser. { - const POLONIEX_CLIENT_MODULE = require('./Exchanges/' + 'PoloniexAPIClient'); - let poloniexApiClient = POLONIEX_CLIENT_MODULE.newPoloniexAPIClient(requestParameters[3], requestParameters[4]); - switch (requestParameters[2]) { + /* We are going to let access the exchange only to authenticated users, that measn that we need the a valid session token. */ - case "returnOpenOrders": { - poloniexApiClient.API.returnOpenOrders(requestParameters[5], requestParameters[6], onExchangeResponse); - break; + let sessionToken = requestParameters[3]; + + for (let i = 0; i < authenticatedSession.length; i++) { + + let session = authenticatedSession[i]; + + if (session.sessionToken === sessionToken) { + + let exchangeKey = session.exchangeKeys[0].key; // 0 because we only deal with one exchange for now. + let exchangeSecret = session.exchangeKeys[0].secret; + + const POLONIEX_CLIENT_MODULE = require('./Exchanges/' + 'PoloniexAPIClient'); + let poloniexApiClient = POLONIEX_CLIENT_MODULE.newPoloniexAPIClient(exchangeKey, exchangeSecret); + + switch (requestParameters[2]) { + + case "returnOpenOrders": { + poloniexApiClient.API.returnOpenOrders(requestParameters[4], requestParameters[5], onExchangeResponse); + break; + } + + case "returnOrderTrades": { + poloniexApiClient.API.returnOrderTrades(requestParameters[4], onExchangeResponse); + break; + } + + case "buy": { + poloniexApiClient.API.buy(requestParameters[4], requestParameters[5], requestParameters[6], requestParameters[7], onExchangeResponse); + break; + } + + case "sell": { + poloniexApiClient.API.sell(requestParameters[4], requestParameters[5], requestParameters[6], requestParameters[7], onExchangeResponse); + break; + } + + case "moveOrder": { + poloniexApiClient.API.moveOrder(requestParameters[4], requestParameters[5], requestParameters[6], onExchangeResponse); + break; + } + + case "returnTicker": { + poloniexApiClient.API.returnTicker(onExchangeResponse); + break; + } + } + + function onExchangeResponse(err, exchangeResponse) { + + /* Delete these secrets before they get logged. */ + + requestParameters[3] = ""; + + let serverResponse = { + err: err, + exchangeResponse: exchangeResponse + } + + respondWithContent(JSON.stringify(serverResponse), response); + } + + return; } - - case "returnOrderTrades": { - poloniexApiClient.API.returnOrderTrades(requestParameters[5], onExchangeResponse); - break; - } - - case "buy": { - poloniexApiClient.API.buy(requestParameters[5], requestParameters[6], requestParameters[7], requestParameters[8], onExchangeResponse); - break; - } - - case "sell": { - poloniexApiClient.API.sell(requestParameters[5], requestParameters[6], requestParameters[7], requestParameters[8], onExchangeResponse); - break; - } - - case "moveOrder": { - poloniexApiClient.API.moveOrder(requestParameters[5], requestParameters[6], requestParameters[7], onExchangeResponse); - break; - } - - case "returnTicker": { - poloniexApiClient.API.returnTicker(onExchangeResponse); - break; - } - } - - function onExchangeResponse(err, exchangeResponse) { - - /* Delete these secrets before they get logged. */ - - requestParameters[3] = ""; - requestParameters[4] = ""; - - let serverResponse = { - err: err, - exchangeResponse: exchangeResponse - } - - respondWithContent(JSON.stringify(serverResponse), response); } } break;