diff --git a/.gitignore b/.gitignore
index 1d04c6e..3a92ee4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,4 +2,5 @@
/package-lock.json
/args/config.json
/args/param.json
+/args/keys.json
*test*
\ No newline at end of file
diff --git a/args/config-sample.json b/args/config-sample.json
deleted file mode 100644
index f380d30..0000000
--- a/args/config-sample.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "secret": "Secret_For_Session__Enter_A_Strong_String(Text/Password)",
- "blockchain_id": "FLO_ID_of_the_admin",
- "blockchain_private": "Private_Key_of_the_Admin",
- "port": "8080",
-
- "sql_user": "mySQL_user",
- "sql_pwd": "mySQL_password",
- "sql_db": "supernode",
- "sql_host": "localhost"
-}
\ No newline at end of file
diff --git a/schema.sql b/args/schema.sql
similarity index 100%
rename from schema.sql
rename to args/schema.sql
diff --git a/src/floGlobals.js b/public/floGlobals.js
similarity index 91%
rename from src/floGlobals.js
rename to public/floGlobals.js
index 4d9a177..6d7bc6b 100644
--- a/src/floGlobals.js
+++ b/public/floGlobals.js
@@ -8,6 +8,7 @@ const floGlobals = {
FLO: ['https://livenet.flocha.in/', 'https://flosight.duckdns.org/'],
FLO_TEST: ['https://testnet-flosight.duckdns.org', 'https://testnet.flocha.in/']
},
+ adminID: "FKAEdnPfjXLHSYwrXQu377ugN4tXU7VGdf",
sendAmt: 0.001,
fee: 0.0005,
tokenURL: "https://ranchimallflo.duckdns.org/",
diff --git a/public/home.html b/public/home.html
index 7d84570..d98cf08 100644
--- a/public/home.html
+++ b/public/home.html
@@ -7,28 +7,7 @@
border: 1px solid black;
}
-
-
+
diff --git a/setup/configure-settings.js b/setup/configure-settings.js
new file mode 100644
index 0000000..738c7ef
--- /dev/null
+++ b/setup/configure-settings.js
@@ -0,0 +1,90 @@
+const fs = require('fs');
+const getInput = require('./getInput');
+
+var config, flag = false;
+try {
+ config = require('./args/config.json');
+ flag = true;
+} catch (error) {
+ config = {
+ "secret": null,
+ "blockchain_id": null,
+ "blockchain_private": null,
+ "port": "8080",
+
+ "sql_user": null,
+ "sql_pwd": null,
+ "sql_db": "exchange",
+ "sql_host": "localhost"
+ };
+}
+
+function configurePort() {
+ return new Promise(resolve => {
+ getInput.Text('Enter port', config["port"]).then(port => {
+ config["port"] = port;
+ resolve(true);
+ })
+ })
+};
+
+function configureSQL() {
+ return new Promise(resolve => {
+ getInput.YesOrNo('Do you want to re-configure mySQL connection').then(value => {
+ if (value) {
+ console.log('Enter mySQL connection values: ')
+ getInput.Text('Host', config['sql_host']).then(host => {
+ config['sql_host'] = host;
+ getInput.Text('Database name', config['sql_db']).then(dbname => {
+ config['sql_db'] = dbname;
+ getInput.Text('MySQL username', config['sql_user']).then(sql_user => {
+ config['sql_user'] = sql_user;
+ getInput.Text('Mysql password', config['sql_pwd']).then(sql_pwd => {
+ config['sql_pwd'] = sql_pwd;
+ resolve(true);
+ })
+ })
+ })
+ })
+ } else
+ resolve(false);
+ })
+ })
+};
+
+function configure() {
+ return new Promise((resolve, reject) => {
+ configurePort().then(port_result => {
+ configureSQL().then(sql_result => {
+ fs.writeFile(__dirname + '/../args/config.json', JSON.stringify(config), 'utf8', (err) => {
+ if (err) {
+ console.error(err);
+ return reject(false);
+ }
+ console.log('Configuration successful!');
+ if (sql_result) {
+ getInput.YesOrNo('Do you want to create schema in the database').then(value => {
+ if (value) {
+ const createSchema = require('./create-schema');
+ createSchema().then(result => resolve(result))
+ .catch(error => {
+ console.log('Retry using: \n' + 'npm run create-schema');
+ reject(error);
+ });
+ } else {
+ console.log('To create schema, use: \n' + 'npm run create-schema');
+ resolve(true);
+ }
+ });
+ } else
+ resolve(true);
+ })
+ })
+ });
+ })
+}
+
+if (!module.parent)
+ configure().then(_ => null).catch(_ => null);
+else
+ module.exports = configure;
\ No newline at end of file
diff --git a/setup/create-schema.js b/setup/create-schema.js
new file mode 100644
index 0000000..36a2259
--- /dev/null
+++ b/setup/create-schema.js
@@ -0,0 +1,37 @@
+const fs = require('fs');
+const config = require('./args/config.json');
+let Database = require('./src/database');
+
+function createSchema() {
+ return new Promise((resolve, reject) => {
+ fs.readFile(__dirname + '/../args/schema.sql', 'utf8', (err, data) => {
+ if (err) {
+ console.error(err);
+ return reject(null);
+ }
+ Database(config["sql_user"], config["sql_pwd"], config["sql_db"], config["sql_host"]).then(DB => {
+ let txQueries = data.split(';');
+ txQueries.pop();
+ txQueries = txQueries.map(q => q.trim().replace(/\n/g, ' '));
+ console.log(txQueries);
+ DB.transaction(txQueries).then(_ => {
+ console.log('SQL Schema created successfully!');
+ resolve(true);
+ }).catch(error => {
+ console.error(error.message);
+ console.log('SQL Schema creation failed! Check user permission');
+ reject(true);
+ });
+ }).catch(error => {
+ console.error(error);
+ console.log('Unable to connect to MySQL database! Check user permission');
+ reject(false);
+ });
+ });
+ });
+}
+
+if (!module.parent)
+ createSchema().then(_ => null).catch(_ => null);
+else
+ module.exports = createSchema;
\ No newline at end of file
diff --git a/setup/getInput.js b/setup/getInput.js
new file mode 100644
index 0000000..c0fc277
--- /dev/null
+++ b/setup/getInput.js
@@ -0,0 +1,42 @@
+const readline = require('readline');
+
+const getInput = {
+ Text: function(text, current = null) {
+ return new Promise((resolve) => {
+ let r = readline.createInterface({
+ input: process.stdin,
+ output: process.stdout
+ });
+ r.question(`${text} :` + (current ? `(${current})` : ''), value => {
+ r.close();
+ value = value || current;
+ if (value === null) {
+ console.log("Please enter a value!");
+ this.Text(text, current).then(result => resolve(result));
+ } else
+ resolve(value);
+ });
+ })
+ },
+
+ YesOrNo: function(text, def_value = "YES") {
+ return new Promise((resolve) => {
+ let r = readline.createInterface({
+ input: process.stdin,
+ output: process.stdout
+ });
+ r.question(`${text}? [YES/NO] : (${def_value})`, value => {
+ r.close();
+ value = (value || def_value).toLowerCase();
+ value = ['yes', 'y'].includes(value) ? true : ['no', 'n'].includes(value) ? false : null;
+ if (value === null) {
+ console.log("Please enter a valid value!");
+ this.YesOrNo(text, def_value).then(result => resolve(result));
+ } else
+ resolve(value);
+ });
+ })
+ }
+}
+
+module.exports = getInput;
\ No newline at end of file
diff --git a/setup/help.js b/setup/help.js
new file mode 100644
index 0000000..9f2d8b1
--- /dev/null
+++ b/setup/help.js
@@ -0,0 +1,11 @@
+let message = `
+Exchange market
+
+npm install - Install the app and node modules.
+npm run setup - Finish the setup (configure and reset password).
+npm run configure - Configure the app.
+npm run reset-password - Reset the password (for private-key).
+npm run create-schema - Create the schema in MySQL database.
+npm run help - List all commands.
+npm start - Start the application.
+`;
\ No newline at end of file
diff --git a/setup/post-install.js b/setup/post-install.js
new file mode 100644
index 0000000..e36ffef
--- /dev/null
+++ b/setup/post-install.js
@@ -0,0 +1,33 @@
+const getInput = require("./getInput");
+
+let message = `
+Exchange Market is installed
+To list all commands, use:
+npm run help
+`;
+console.log(message);
+
+getInput.YesOrNo('Do you want to finish the setup now').then(value => {
+ if (value) {
+ let configureSettings = require('./configure-settings');
+ configureSettings()
+ .then(_ => console.log('To Re-configure, use:'))
+ .catch(_ => console.log('Finish the configuration later using: '))
+ .finally(_ => {
+ console.log('npm run configure');
+ getInput.YesOrNo('Do you want to Reset password for private key now').then(value => {
+ if (value) {
+ let resetPassword = require('./reset-password');
+ resetPassword()
+ .then(_ => console.log('To reset the password again, use: '))
+ .catch(_ => console.log('Reset the password later using: '))
+ .finally(_ => {
+ console.log('npm run reset-password');
+ })
+ } else
+ console.log('Reset the password later using:\n' + 'npm run reset-password');
+ })
+ })
+ } else
+ console.log('Finish the setup later using:\n' + 'npm run setup');
+})
\ No newline at end of file
diff --git a/setup/reset-password.js b/setup/reset-password.js
new file mode 100644
index 0000000..be76064
--- /dev/null
+++ b/setup/reset-password.js
@@ -0,0 +1,83 @@
+const fs = require('fs');
+const getInput = require('./getInput');
+
+const floGlobals = require('../public/floGlobals');
+require('../src/set_globals');
+require('../src/lib');
+require('../src/floCrypto');
+
+console.log(__dirname);
+
+function validateKey(privKey) {
+ return new Promise((resolve, reject) => {
+ if (floCrypto.verifyPrivKey(privKey, floGlobals.adminID))
+ return resolve(privKey);
+ else {
+ getInput.Text('Incorrect Private Key! Re-Enter: (Cancel)', 'Cancel').then(value => {
+ if (value === 'Cancel')
+ return reject(true);
+ validateKey(value)
+ .then(result => resolve(result))
+ .catch(error => reject(error))
+ });
+ }
+ })
+}
+
+function getPassword() {
+ return new Promise((resolve, reject) => {
+ getInput.Text(`Enter a password [Minimum 8 characters]`, 'Cancel').then(value1 => {
+ if (value1 === 'Cancel')
+ return reject(true);
+ else if (value1.length < 8) {
+ console.log('Password length must be minimum of 8 characters');
+ getPassword()
+ .then(result => resolve(result))
+ .catch(error => reject(error))
+ } else {
+ getInput.Text(`Re-enter password`).then(value2 => {
+ if (value1 !== value2) {
+ console.log('Passwords doesnot match! Try again.');
+ getPassword()
+ .then(result => resolve(result))
+ .catch(error => reject(error))
+ } else
+ resolve(value1);
+ })
+ }
+ });
+ })
+}
+
+function resetPassword() {
+ return new Promise((resolve, reject) => {
+ getInput.Text(`Enter private key for adminID (${floGlobals.adminID})`).then(value => {
+ validateKey(value).then(privKey => {
+ getPassword().then(password => {
+ let encrypted = Crypto.AES.encrypt(privKey, password);
+ let randNum = floCrypto.randInt(10, 15);
+ let splitShares = floCrypto.createShamirsSecretShares(encrypted, randNum, randNum);
+ fs.writeFile(__dirname + '/../args/keys.json', JSON.stringify(splitShares), 'utf8', (err) => {
+ if (err) {
+ console.error(err);
+ return reject(false);
+ }
+ console.log('Password reset successful!');
+ resolve(true);
+ })
+ }).catch(error => {
+ console.log('Password reset cancelled!');
+ reject(true);
+ })
+ }).catch(error => {
+ console.log('Password reset cancelled!');
+ reject(true);
+ })
+ })
+ })
+}
+
+if (!module.parent)
+ resetPassword().then(_ => null).catch(error => console.error(error));
+else
+ module.exports = resetPassword;
\ No newline at end of file
diff --git a/src/database.js b/src/database.js
index e82ab14..d5b35fd 100644
--- a/src/database.js
+++ b/src/database.js
@@ -66,6 +66,8 @@ function Database(user, password, dbname, host = 'localhost') {
queryFn(result);
}
};
+ if (!Array.isArray(q_i))
+ q_i = [q_i];
if (q_i[1])
conn.query(q_i[0], q_i[1], callback);
else
diff --git a/src/main.js b/src/main.js
index 54e5916..559d7d0 100644
--- a/src/main.js
+++ b/src/main.js
@@ -1,5 +1,5 @@
const config = require('../args/config.json');
-global.floGlobals = require("./floGlobals");
+global.floGlobals = require('../public/floGlobals');
require('./set_globals');
require('./lib');
require('./floCrypto');
@@ -7,22 +7,31 @@ require('./floBlockchainAPI');
const Database = require("./database");
const App = require('./app');
+const floGlobals = require('../public/floGlobals');
const PORT = config['port'];
module.exports = function startServer(public_dir) {
-
- global.myPrivKey = config["blockchain_private"];
- global.myPubKey = floCrypto.getPubKeyHex(global.myPrivKey);
- global.myFloID = floCrypto.getFloID(global.myPubKey);
-
- if (global.myFloID !== config["blockchain_id"] || !floCrypto.verifyPrivKey(global.myPrivKey, global.myFloID)) {
- console.error("Invalid Private Key for adminID");
- return;
+ try {
+ var _tmp = require('../args/keys.json');
+ _tmp = floCrypto.retrieveShamirSecret(_tmp);
+ var _pass = process.env.password;
+ _tmp = Crypto.AES.decrypt(_tmp, _pass);
+ if (floCrypto.verifyPrivKey(_tmp, floGlobals.adminID)) {
+ global.myPrivKey = _tmp;
+ global.myPubKey = floCrypto.getPubKeyHex(global.myPrivKey);
+ global.myFloID = floCrypto.getFloID(global.myPubKey);
+ } else {
+ console.error('Loaded wrong private key!');
+ process.exit(1);
+ }
+ } catch (error) {
+ console.error('Unable to load private key!');
+ process.exit(1);
}
- floGlobals.adminID = config["blockchain_id"];
+
global.PUBLIC_DIR = public_dir;
- console.log(PUBLIC_DIR, global.myFloID);
-
+ console.debug(PUBLIC_DIR, global.myFloID);
+
Database(config["sql_user"], config["sql_pwd"], config["sql_db"], config["sql_host"]).then(DB => {
const app = App(config['secret'], DB);
app.listen(PORT, () => console.log(`Server Running at port ${PORT}`));