From 04dc6453a15e8dc85ce0b6909537fc93210a9991 Mon Sep 17 00:00:00 2001 From: kolitha warnakulasooriya Date: Tue, 7 Jan 2020 10:50:37 +0530 Subject: [PATCH 1/5] initial commitment --- .vscode/launch.json | 7 +- framework/db.js | 2 - framework/jsondb.js | 16 ++ framework/mysqldb.js | 431 ++--------------------------------- framework/server.js | 29 ++- index.js | 15 +- package.json | 3 +- public/scripts/viewDomain.js | 31 +++ routes/other.js | 44 ++++ views/domain/viewDomain.ejs | 34 +++ 10 files changed, 190 insertions(+), 422 deletions(-) create mode 100644 routes/other.js diff --git a/.vscode/launch.json b/.vscode/launch.json index 73b7a5c..f5c514c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,11 +4,12 @@ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ + { "type": "node", - "request": "launch", - "name": "Launch Program", - "program": "${workspaceFolder}/index.js" + "request": "attach", + "name": "Attach", + "port": 9229, } ] } \ No newline at end of file diff --git a/framework/db.js b/framework/db.js index adce832..13cc6a9 100644 --- a/framework/db.js +++ b/framework/db.js @@ -2,6 +2,4 @@ const {DB_SELECT} = require('../config'); if(DB_SELECT === 'json'){ module.exports = require('./jsondb'); -}else{ - module.exports = require('./mysqldb') } \ No newline at end of file diff --git a/framework/jsondb.js b/framework/jsondb.js index 06dda4d..2747289 100644 --- a/framework/jsondb.js +++ b/framework/jsondb.js @@ -30,6 +30,22 @@ Database.prototype.createTables = async function() { } +Database.prototype.getMysqlConfigs = async function() { + try { + return await db.getData(`/mysqlConfig/`); + } catch (error) { + return null; + } +}; + +Database.prototype.setMysqlConfigs = async function(value) { + try { + await db.push(`/mysqlConfig/`, value, true); + } catch (error) { + return null; + } +}; + Database.prototype.getAllDomains = async function() { const domains = []; const domainPaths = await db.getData("/domains") || []; diff --git a/framework/mysqldb.js b/framework/mysqldb.js index 8c157fa..4ddfc0b 100644 --- a/framework/mysqldb.js +++ b/framework/mysqldb.js @@ -1,418 +1,37 @@ -const JsonDB = require("node-json-db"); const mysql = require('mysql'); -const bcrypt = require("bcrypt"); -const uuidv1 = require("uuid/v1"); -const logger = require("../framework/logger"); -const { DB_PATH, MYSQL_DATABASE, MYSQL_HOST, MYSQL_PASSWORD, MYSQL_USERNAME } = require('../config'); -const { Config } = require("node-json-db/dist/lib/JsonDBConfig"); +const Database = require("./db"); -const db = new JsonDB(new Config(DB_PATH || "resource/database/jsonStore", true, false)); -let instance = null; +let connection; -const SALT_ROUNDS = 2; -const STATE = { - AUTHENTICATED: 'authenticated' +const getConnectionString = function(database){ + const config = Database.getMysqlConfigs(); + return mysql.createConnection({ + host : config.host, + user : config.username, + password : config.password, + database : database + }); } -const TABLES = { - DOMAINS: 'domains', - PATHS: 'paths' +const connect = function(){ + return 'X'; + connection = getConnectionString(); + connection.connect(); } -const Database = function() { - if (instance === null) { - instance = this; - } - this.connection = mysql.createConnection({ - host: MYSQL_HOST, - user: MYSQL_USERNAME, - password: MYSQL_PASSWORD, - database: MYSQL_DATABASE - }) - return this; -}; - -Database.prototype.connect = function() { - const connection = this.connection; - return new Promise(function(resolve, reject) { - connection.connect(function(err) { - if (err) { - logger.error(`Mysql Connection Error ${err}`); - return reject(err); - } - logger.info(`Mysql Connected ${connection.threadId}`); - return resolve(connection.threadId) - }); - }) -} - -Database.prototype.disconnect = function() { - const connection = this.connection; - return new Promise(function(resolve, reject) { - connection.end(function(err) { - if (err) { - logger.error(`Mysql Disconnection Error ${err}`); - return reject(err); - } - logger.info(`Mysql Disconnected ${connection.threadId}`); - return resolve(connection.threadId) - }); - }) -} - -Database.prototype.query = function(query) { - logger.info(query) - return new Promise(async(resolve, reject) => { - if (this.connection.state !== STATE.AUTHENTICATED) { - await this.connect() - } - this.connection.query(query, function(error, results, fields) { - if (error) { - logger.error(`Mysql Query Error ${error}`); - return reject(error); - }; - return resolve(results); - }); - }) - -} - -Database.prototype.createTables = async function() { - // domain table - return new Promise(async(resolve, reject) => { - try { - let query = `CREATE TABLE IF NOT EXISTS domains ( - id INT AUTO_INCREMENT PRIMARY KEY, - domainId VARCHAR(36) NOT NULL, - domainName VARCHAR(255) NOT NULL - ) ENGINE=INNODB;`; - - await this.query(query); - - query = `CREATE TABLE IF NOT EXISTS paths ( - id INT AUTO_INCREMENT PRIMARY KEY, - domainId VARCHAR(36) NOT NULL, - pathId VARCHAR(36) NOT NULL, - pathName VARCHAR(255) NOT NULL, - pathUrl VARCHAR(255) NOT NULL, - pathMethod VARCHAR(255) NOT NULL, - pathStatus VARCHAR(255) NOT NULL, - pathDescription VARCHAR(255) NULL, - header TEXT NOT NULL, - authentication BOOL, - body LONGTEXT NULL - ) ENGINE=INNODB;` - - await this.query(query); - - resolve(true); - } catch (error) { - logger.error(`Mysql Create tables Error ${err}`); - reject(false) - } - }) -} - -Database.prototype.rowExists = async function(tablename, filter) { - const results = await this.query(`SELECT * FROM ${tablename} WHERE ${filter}`); - return results; -} - -Database.prototype.addDomain = async function(domainName) { - if (!domainName) { - logger.error(`Domain Name NotINNER Found`); - return false; - } - const id = uuidv1(); - try { - const exists = await this.rowExists(TABLES.DOMAINS, `domainName='${domainName}'`); - if (exists.length <= 0) { - await this.query(`INSERT INTO ${TABLES.DOMAINS}(domainId,domainName) VALUES ('${id}','${domainName}')`) - return id; - } - return exists[0].domainId; - } catch (error) { - logger.error(` ${error}`); - return false; - } -}; - -Database.prototype.getAllDomains = async function() { - - const domains = []; - const domainPaths = await this.query(`SELECT domainId, domainName FROM ${TABLES.DOMAINS}`); - for (let i = 0; i < domainPaths.length; i++) { - const domain = domainPaths[i]; - const pathsCount = await this.query(`SELECT COUNT(pathId) as pathCount FROM ${TABLES.PATHS} WHERE domainId='${domain.domainId}'`); - domains.push({ - domainId: domain.domainId, - domainName: domain.domainName, - pathCount: pathsCount[0].pathCount - }) - } - return domains; -}; - -Database.prototype.getAllPaths = async function() { - const results = await this.query(`SELECT domains.domainId,domains.domainName,paths.pathId,paths.pathName,paths.pathUrl,paths.pathMethod,paths.pathStatus,paths.pathDescription,paths.header,paths.authentication,paths.body FROM ${TABLES.DOMAINS} as domains INNER JOIN ${TABLES.PATHS} as paths ON domains.domainId=paths.domainId`); - return results; -}; - -Database.prototype.getDomainFromId = async function(domainId) { - const domain = await this.query(`SELECT domainId, domainName FROM ${TABLES.DOMAINS} WHERE domainId='${domainId}'`) - if (domain.length > 0) { - return domain[0]; - } - return null; -}; - -Database.prototype.getPathNamesForDomain = async function(domainId) { - const pathNames = []; - const results = await this.query(`SELECT * FROM ${TABLES.PATHS} WHERE domainId = '${domainId}'`); - results.forEach(result => pathNames.push(result)); - return pathNames; -}; - -Database.prototype.updateDomainName = async function(domainId, domainName) { - await this.query(`UPDATE ${TABLES.DOMAINS} SET domainName ='${domainName}' WHERE domainId = '${domainId}'`); -}; - -Database.prototype.deleteDomain = async function(domainId) { - await this.query(`DELETE FROM ${TABLES.DOMAINS} WHERE domainId = '${domainId}'`); -}; - -Database.prototype.getPathsFromDomainId = async function(domainId) { - const results = await this.query(`SELECT domains.domainId,domains.domainName,paths.pathId,paths.pathName,paths.pathUrl,paths.pathMethod,paths.pathStatus,paths.pathDescription,paths.header,paths.authentication,paths.body FROM ${TABLES.DOMAINS} as domains INNER JOIN ${TABLES.PATHS} as paths ON domains.domainId=paths.domainId WHERE domains.domainId='${domainId}'`); - if (results.length > 0) { - return { - domainName: results[0].domainName, - paths: results - } - } - const domain = await this.getDomainFromId(domainId); - return { - domainName: domain.domainName, - paths: [] - } -} - -Database.prototype.addPath = async function(domainId, record, id = uuidv1()) { - const query = `INSERT INTO ${TABLES.PATHS}(domainId,pathId,pathName,pathUrl,pathMethod,pathStatus,pathDescription,header,authentication,body) values('${domainId}','${id}','${record.pathName}','${record.pathUrl}','${record.pathMethod}','${record.pathStatus}','${record.pathDescription}','${JSON.stringify(record.header)}',${record.authentication},'${record.body}')` - await this.query(query) - return id; -}; - -Database.prototype.getExistedPathId = async function({ domainName, pathUrl, pathMethod, pathStatus }) { - const results = await this.query(`SELECT domains.domainId,paths.pathId,paths.authentication - FROM ${TABLES.DOMAINS} as domains LEFT JOIN ${TABLES.PATHS} as paths - ON domains.domainId=paths.domainId - WHERE domains.domainName='${domainName}' AND paths.pathUrl = '${pathUrl}' AND paths.pathMethod = '${pathMethod}'`); - if (results.length > 0) { - return { - domainId: results[0].domainId, - pathId: results[0].pathId, - authentication: results[0].authentication === 0 ? false : true - } - } else { - return {} - } +const disconnect = function(){ + connection.end(); } -Database.prototype.getPath = async function(domainId, pathId) { - const results = await this.query(`SELECT domains.domainId,domains.domainName,paths.pathId,paths.pathName,paths.pathUrl,paths.pathMethod,paths.pathStatus,paths.pathDescription,paths.header,paths.authentication,paths.body FROM ${TABLES.DOMAINS} as domains INNER JOIN ${TABLES.PATHS} as paths ON domains.domainId=paths.domainId WHERE domains.domainId='${domainId}' AND paths.pathId = '${pathId}'`); - if (results.length > 0) { - return { - domainName: results[0].domainName, - paths: results - } - } - const domain = await this.getDomainFromId(domainId); - if (domain === null) { - return { - domainName: null, - paths: [] - } - } - return { - domainName: domain.domainName, - paths: [] - } +const reconnect = function(){ + disconnect(); + connect(); } -Database.prototype.updatePath = async function(domainId, pathId, record) { - const query = `UPDATE ${TABLES.PATHS} SET - pathName='${record.pathName}', - pathUrl='${record.pathUrl}', - pathMethod='${record.pathMethod}', - pathStatus='${record.pathStatus}', - pathDescription='${record.pathDescription}', - header='${JSON.stringify(record.header)}', - authentication=${record.authentication}, - body='${record.body}' WHERE domainId='${domainId}' AND pathId='${pathId}'` - await this.query(query); -}; - -Database.prototype.deletePath = async function(domainId, pathId) { - await this.query(`DELETE FROM ${TABLES.PATHS} WHERE domainId = '${domainId}' AND pathId = '${pathId}'`); -}; - -Database.prototype.getPathsForDomain = function(domainId) { - return db.getData(`/domains[${domainId}]`).paths; -}; - -Database.prototype.deleteAllUsers = function(domainId, pathId, record) { - db.delete(`/users`); -}; - -Database.prototype.deleteUsers = function(id) { - - db.delete(`/users[${id}]`); -}; - -Database.prototype.setUser = function(username, password, userEmail, id) { - bcrypt.hash(password, SALT_ROUNDS, function(err, hash) { - if (err) { - throw new Error(err); - } - const user = { - id: id || uuidv1(), - username, - userEmail, - password: hash - }; - db.push(`/users[]`, user, true); - }); -}; - -Database.prototype.getAllUsers = function() { - return db.getData("/users"); -}; - -const checkValidity = async function(username, password, user) { - return bcrypt - .compare(password, user.password) - .then(function(res) { - if (res) { - if (user.username === username) { - return { - username, - action: true - }; - } - return { - username, - action: false - }; - } - }) - .catch(function(error) { - throw new Error(error); - }); -}; - -Database.prototype.getUser = async function(username, password) { - const users = db.getData(`/users`); - - let userFound = false; - let userId = null; - let counter = 0; - for (user of users) { - counter = counter + 1; - try { - const userinfo = await checkValidity(username, password, user); - if (!userinfo.action) { - continue; - } - userFound = true; - userId = user.id; - break; - } catch (error) { - continue; - } - } - if (userFound) { - return { - userId, - username, - counter, - action: true - }; - } - return { - userId, - username, - counter, - action: false - }; -}; - -Database.prototype.getUserFromUsername = async function(username) { - const users = db.getData(`/users`); - let counter = 0; - for (user of users) { - if (user.username === username) { - return { - ...user, - counter - } - } - counter = counter + 1; - } - return null; -}; - -Database.prototype.saveCustomCommand = function(key, value) { - db.push(`/userCommands/${key}/`, value, true); - return ""; -}; - -Database.prototype.getCustomCommand = function(key, value) { - return db.getData(`/userCommands/${key}/`); -}; - -Database.prototype.delCustomCommand = function(key, value) { - db.delete(`/userCommands/${key}/`); - return ""; -}; - -Database.prototype.flushAllUserData = function(data) { - db.delete(`/userCommands/`); -} - - -Database.prototype.setEnableUpload = function(data) { - db.push('/upload/', data, true) -} - -Database.prototype.getEnableUpload = function(data) { - return db.getData('/upload/') -} - -Database.prototype.saveToken = function(token) { - db.push(`/authToken/`, token, true); -}; - -Database.prototype.getToken = function(token) { - return db.getData(`/authToken/`); -}; - -Database.prototype.saveApiUrl = function(url) { - db.push(`/apiUrl/`, url, true); -}; - -Database.prototype.getApiUrl = function() { - return db.getData(`/apiUrl/`); -}; - -Database.prototype.saveResetToken = function(token) { - db.push(`/resetToken/`, token, true); -}; - -Database.prototype.getResetToken = function() { - return db.getData(`/resetToken/`); -}; -Database.prototype.deleteResetToken = function() { - db.delete(`/resetToken/`); -}; +//const query = connection.query; -module.exports = new Database(); \ No newline at end of file +module.exports = { + connect, + disconnect, + reconnect +} \ No newline at end of file diff --git a/framework/server.js b/framework/server.js index e0cf1f0..19fcf7e 100644 --- a/framework/server.js +++ b/framework/server.js @@ -64,6 +64,10 @@ Server.prototype.init = async function(port) { this.status = 'Started'; }; +Server.prototype.getPort = function(){ + return this.port; +} + function changeResponseBody(params, body) { const values = Object.values(params); let objectBody = body; @@ -175,18 +179,25 @@ async function execProgCommand(match, response) { const path = require('path'); const underscore = require('underscore'); const faker = require('faker'); - ${params}`; + const mysql = require('./mysqldb'); + try{ + ${params} + }catch(){}`; const AsyncFunction = Object.getPrototypeOf(async function() {}).constructor; - const value = await new AsyncFunction( - 'exports', - 'require', - 'module', - '__filename', - '__dirname', - params - )(exports, require, module, __filename, __dirname); + const value = ""; + try { + await new AsyncFunction( + 'exports', + 'require', + 'module', + '__filename', + '__dirname', + params + )(exports, require, module, __filename, __dirname); + } catch (error) { + } return returnResponse.replace(/#prog_value#/g, value); } diff --git a/index.js b/index.js index bf30c49..845197e 100644 --- a/index.js +++ b/index.js @@ -4,10 +4,12 @@ const _ = require("lodash"); const bodyParser = require("body-parser"); const cookieParser = require("cookie-parser"); const session = require("express-session"); +const nodeadmin = require('nodeadmin'); const logger = require("./framework/logger"); const domainRouter = require("./routes/domainRouter"); const pathRouter = require("./routes/pathRoutes"); const schedulers = require("./routes/shedulers"); +const otherRoutes = require("./routes/other"); const uuidv1 = require("uuid/v1"); const db = require("./framework/db"); const { getPublicIP } = require("./framework/utils"); @@ -20,7 +22,6 @@ const systemApp = express(); systemApp.set("view engine", "ejs"); systemApp.use(express.static("public")); - systemApp.use(cookieParser()); systemApp.use( session({ @@ -61,6 +62,7 @@ systemApp.use((req, res, next) => { }); const sessionChecker = (req, res, next) => { + return next(); if (req.session.user && req.cookies.userId) { next(); } else { @@ -202,6 +204,15 @@ systemApp.post("/flushAll", function(req, res) { } }); +systemApp.post("/saveMysqlConfig", function(req, res) { + try { + db.setMysqlConfigs(req.body); + res.send({ success: true }); + } catch (error) { + res.send({ success: false }); + } +}); + systemApp.post("/upload", async function(req, res) { const isEnable = db.getEnableUpload().enable == "true"; if (!isEnable) { @@ -339,10 +350,12 @@ systemApp.post("/upload", async function(req, res) { systemApp.use("/domain", sessionChecker, domainRouter); systemApp.use("/domain/paths", sessionChecker, pathRouter); systemApp.use("/schedulers", sessionChecker, schedulers); +systemApp.use("/other",sessionChecker,otherRoutes); (async function() { await db.createTables(); Server().app.use(ADMIN_PREFIX, systemApp); + Server().app.use(nodeadmin(Server().app)); Server().app.get('/', (req, res) => res.redirect(`${ADMIN_PREFIX}/`)) await Server().init(port); })() diff --git a/package.json b/package.json index 01d41ee..58c24b8 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,8 @@ "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", - "start": "node index.js" + "start": "node index.js", + "debug": "node --inspect index.js" }, "keywords": [ "mockable", diff --git a/public/scripts/viewDomain.js b/public/scripts/viewDomain.js index f7baca1..452c8ea 100644 --- a/public/scripts/viewDomain.js +++ b/public/scripts/viewDomain.js @@ -9,6 +9,37 @@ function onSchedulerClick(){ window.location.href = `/admin/schdulers`; } +function configureMysql(){ + const data = { + host: document.getElementById("host").value || "localhost:3306", + username: document.getElementById("username").value || "root", + password: document.getElementById("password").value || "password" + } + + $.ajax({ + type: 'POST', + url: '/admin/saveMysqlConfig', + data + }); +} + +function handleOnNodeAdmin(){ + $.ajax({ + type: 'GET', + url: '/admin/other/nodeAdmin', + success: function(data) { + window.localStorage.setItem('nodeadmin', data.token); + var win = window.open(data.reload, '_blank'); + win.focus(); + }, + error: function(data) { + var win = window.open(data.reload, '_blank'); + win.focus(); + } + }); + +} + function generateUUID() { var d = new Date().getTime(); if (typeof performance !== 'undefined' && typeof performance.now === 'function') { diff --git a/routes/other.js b/routes/other.js new file mode 100644 index 0000000..9aff904 --- /dev/null +++ b/routes/other.js @@ -0,0 +1,44 @@ +const express = require("express"); +const fetch = require('node-fetch'); +const Server = require('../framework/server'); +const otherRouter = express.Router(); +const Database = require("../framework/db"); +const Logger = require("../framework/logger"); +const {HOST} = require("../config"); + +// view domains +otherRouter.get("/nodeAdmin", async function(req, res) { + const mysqlConfigs = await Database.getMysqlConfigs(); + + if(!mysqlConfigs){ + return res.redirect('/nodeadmin') + } + + const url = `http://${HOST}:${Server().getPort()}/nodeadmin/api/auth/login` + const reload = `http://${HOST}:${Server().getPort()}/nodeadmin/#!/db`; + const body = { + mysqlUser: mysqlConfigs.username, + mysqlPassword: mysqlConfigs.password, + mysqlHost:mysqlConfigs.host + } + try { + const response = await fetch(url,{method: "POST", body: JSON.stringify(body), headers: { + 'Content-Type': 'application/json' + }}); + const data = await response.json(); + if(data.token){ + return res.json({ + reload, + token: data.token + }); + } + } catch (error) { + Logger.error(error); + } + return res.json({ + reload + }); +}); + + +module.exports = otherRouter; \ No newline at end of file diff --git a/views/domain/viewDomain.ejs b/views/domain/viewDomain.ejs index 21e3311..a0bc49a 100644 --- a/views/domain/viewDomain.ejs +++ b/views/domain/viewDomain.ejs @@ -50,6 +50,7 @@ >
Schedulers <%= runs %> + Node Admin
@@ -72,6 +73,7 @@ +
@@ -100,6 +102,38 @@ + +