Merge pull request #1 from sairajzero/main

This commit is contained in:
Sai Raj 2021-10-07 17:43:39 +05:30 committed by GitHub
commit d1bb6e6d2e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 386 additions and 34 deletions

1
.gitignore vendored
View File

@ -2,4 +2,5 @@
/package-lock.json
/args/config.json
/args/param.json
/args/keys.json
*test*

View File

@ -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/",

View File

@ -114,6 +114,16 @@ function getTransactionList() {
});
}
function getRate() {
return new Promise((resolve, reject) => {
fetch('/get-rate')
.then(result => responseParse(result, false)
.then(result => resolve(result))
.catch(error => reject(error)))
.catch(error => reject(error));
});
}
function signRequest(request, privKey) {
if (typeof request !== "object")
throw Error("Request is not an object");

View File

@ -2,6 +2,7 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
@ -9,31 +10,14 @@
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" rel="stylesheet">
<script id="floGlobals">
/* Constants for FLO blockchain operations !!Make sure to add this at beginning!! */
const floGlobals = {
//Required for all
blockchain: "FLO",
//Required for blockchain API operators
apiURL: {
FLO: ['https://livenet.flocha.in/', 'https://flosight.duckdns.org/'],
FLO_TEST: ['https://testnet-flosight.duckdns.org/', 'https://testnet.flocha.in/']
},
tokenURL: "https://ranchimallflo.duckdns.org/",
token: "rupee",
adminID: "FKAEdnPfjXLHSYwrXQu377ugN4tXU7VGdf",
sendAmt: 0.001,
fee: 0.0005,
}
</script>
<script src="floGlobals.js"></script>
<script src="https://sairajzero.github.io/Standard_Operations/cdn/floCrypto.js"></script>
<script src="https://github.com/sairajzero/Standard_Operations/releases/download/test/floBlockchainAPI.js"></script>
<script src="fn.js"></script>
</head>
<body>
<div>Current FLO Rate: <span id="cur-rate"></span></div>
<form id="login-form">
<fieldset>
<legend>Login</legend>
@ -682,6 +666,14 @@
}).catch(error => console.error(error))
}
function get_rate() {
getRate().then(rate => {
console.log("Rate: ", rate);
let container = document.getElementById("cur-rate");
container.textContent = "Rs " + parseFloat(rate).toFixed(2);
}).catch(error => console.error(error))
}
function refresh(init = false) {
if (init)
console.info("init");
@ -690,6 +682,7 @@
list_buy();
list_sell();
list_txns();
get_rate();
if (init || document.getElementById('user-container').style.display === "block")
account();
}

120
setup/configure-settings.js Normal file
View File

@ -0,0 +1,120 @@
const fs = require('fs');
const getInput = require('./getInput');
var config, flag_new;
try {
config = require('./args/config.json');
flag_new = false;
} catch (error) {
config = {
"secret": null,
"port": "8080",
"sql_user": null,
"sql_pwd": null,
"sql_db": "exchange",
"sql_host": "localhost"
};
flag_new = true;
}
function flaggedYesOrNo(text) {
return new Promise((resolve) => {
if (flag_new)
resolve(true);
else
getInput.YesOrNo(text)
.then(result => resolve(result))
.catch(error => reject(error))
})
}
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 => {
flaggedYesOrNo('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 randomizeSessionSecret() {
return new Promise((resolve) => {
flaggedYesOrNo('Do you want to randomize the session secret').then(value => {
if (value) {
let N = Math.floor(Math.random() * (64 - 32 + 1)) + 32;
var secret = '';
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
for (var i = 0; i < N; i++)
secret += characters.charAt(Math.floor(Math.random() * characters.length));
config['secret'] = secret
resolve(true);
} else
resolve(false);
})
})
}
function configure() {
return new Promise((resolve, reject) => {
configurePort().then(port_result => {
randomizeSessionSecret().then(secret_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;

37
setup/create-schema.js Normal file
View File

@ -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;

42
setup/getInput.js Normal file
View File

@ -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;

11
setup/help.js Normal file
View File

@ -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.
`;

33
setup/post-install.js Normal file
View File

@ -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');
})

83
setup/reset-password.js Normal file
View File

@ -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;

View File

@ -50,8 +50,9 @@ module.exports = function App(secret, DB) {
app.get('/list-sellorders', Request.ListSellOrders);
app.get('/list-buyorders', Request.ListBuyOrders);
//list all process transactions
//list all process transactions and rate
app.get('/list-transactions', Request.ListTransactions);
app.get('/get-rate', Request.getRate)
//get account details
app.get('/account', Request.Account);

View File

@ -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

View File

@ -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}`));

View File

@ -52,8 +52,6 @@ const tokenAPI = {
}
}
function getRates() {
return new Promise((resolve, reject) => {
getRates.FLO_USD().then(FLO_rate => {
@ -92,6 +90,10 @@ getRates.USD_INR = function() {
});
}
function returnRates() {
return net_FLO_price;
}
function addSellOrder(floID, quantity, min_price) {
return new Promise((resolve, reject) => {
if (!floID || !floCrypto.validateAddr(floID))
@ -657,6 +659,7 @@ function transactionReCheck() {
}
module.exports = {
returnRates,
addBuyOrder,
addSellOrder,
cancelOrder,

View File

@ -243,6 +243,11 @@ function ListTransactions(req, res) {
.catch(error => res.status(INTERNAL.e_code).send("Try again later!"));
}
function getRate(req, res) {
let rate = market.returnRates();
res.send(`${rate}`);
}
function Account(req, res) {
const setLogin = function(message) {
let randID = floCrypto.randString(16, true);
@ -409,6 +414,7 @@ module.exports = {
ListSellOrders,
ListBuyOrders,
ListTransactions,
getRate,
Account,
DepositFLO,
WithdrawFLO,