diff --git a/.gitignore b/.gitignore index 3c3629e..0b4836b 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ node_modules +server-api/config.json \ No newline at end of file diff --git a/server-api/app.js b/server-api/app.js index 5f5e7d7..adb4b65 100644 --- a/server-api/app.js +++ b/server-api/app.js @@ -2,6 +2,19 @@ const koa = require('koa'); const path = require('path'); const fs = require('fs'); +// Load config +const config = require('./config.json'); +// custom modules +const mysql = require('./libs/mysql_pool'); + +// init mysql connection pool +mysql.database = config.db.mysql.dbname; +mysql.host = config.db.mysql.host; +mysql.user = config.db.mysql.user; +mysql.password = config.db.mysql.pass; +mysql.port = config.db.mysql.port; +mysql.createPool(); + // Koa Middleware const session = require('koa-session'); const Router = require('koa-router'); @@ -40,6 +53,12 @@ app.use(session({ app.use(router.routes()); app.use(router.allowedMethods()); +// load other route +const api_route = require('./route/api'); + +// set other route +router.use("/api", api_route.routes()); + router.get('/', async(c, n) => { c.body = 'Get root'; }); \ No newline at end of file diff --git a/server-api/config.json.default b/server-api/config.json.default new file mode 100644 index 0000000..4de3283 --- /dev/null +++ b/server-api/config.json.default @@ -0,0 +1,18 @@ +{ + "db": { + "mysql": { + "user": "root", + "pass": "", + "host": "localhost", + "port": 3306, + "dbname": "lora" + }, + "mongo": { + "user": "", + "pass": "", + "host": "localhost", + "port": 27017, + "dbname": "lora" + } + } +} \ No newline at end of file diff --git a/server-api/libs/crypto.js b/server-api/libs/crypto.js new file mode 100644 index 0000000..09e705c --- /dev/null +++ b/server-api/libs/crypto.js @@ -0,0 +1,31 @@ +var crypto = require('crypto'); + +var random = (len = 32) => { + var buf = crypto.randomBytes(len); + return buf.toString("hex"); +} + +var sha256 = (str) => { + return crypto.createHash("sha256").update(str).digest('base64'); +} + +var genPassHash = (str) => { + var hash = random(16); + var pass = sha256(str + hash); + return `$${hash}$${pass}`; +} + +var comparePass = (plain, hash) => { + var match = hash.match(/^\$(.+?)\$(.+)$/); + if (match == null || match.length < 3 || !match[1] || !match[2]) return false; + var pass = sha256(plain + match[1]); + if (pass == match[2]) return true; + return false; +} + +module.exports = { + random, + sha256, + genPassHash, + comparePass +} \ No newline at end of file diff --git a/server-api/libs/mysql_pool.js b/server-api/libs/mysql_pool.js new file mode 100644 index 0000000..2c36334 --- /dev/null +++ b/server-api/libs/mysql_pool.js @@ -0,0 +1,119 @@ +const mysql = require('mysql'); + +class MySQLPool { + constructor() { + this._user = ''; + this._password = ''; + this._host = ''; + this._port = 3306; + this._database = ''; + this._socketPath = '' + this._pool = null; + this.autoclose = false; + this._useSocket = false; + } + + createPool() { + let json = { + connectionLimit: 30, + user: this._user, + password: this._password, + host: this._host, + port: this._port, + socketPath: this._socketPath + }; + if (this._useSocket) { + delete json.host; + delete json.port; + } else { + delete json.socketPath; + } + this._pool = mysql.createPool(json); + } + + async getConn() { + return new Promise((resolve, reject) => { + this._pool.getConnection((err, conn) => { + if (err) return reject(err); + return resolve(conn) + }) + }) + } + + formatQuery(query, arg) { + return mysql.format(query, arg); + } + + escape(val) { + return mysql.escape(val); + } + + recordPage(rows, page, maxPage) { + if (!page || !isFinite(page) || page < 1) page = 1; + + let totalpage = Math.ceil(rows / maxPage); + + let prevpage = page - 1; + let nextpage = page + 1; + + if (prevpage < 1) prevpage = 1; + if (nextpage > totalpage) nextpage = totalpage; + + let rec_start = (page - 1) * maxPage + 1 + let rec_end = (rec_start + maxPage - 1); + if (rec_end > rows) rec_end = rows; + + let json = { + rec_start, + rec_end, + total: rows, + prevpage, + nextpage, + totalpage, + page + }; + + return json; + } + + set user(str) { this._user = str; } + set host(str) { this._host = str; } + set password(str) { this._password = str; } + set port(str) { this._port = str; } + set database(str) { this._database = str; } +} + + +// let Pool = ((opts) => { +// let defOpts = { +// user: 'root', +// pass: '', +// host: 'localhost', +// port: 3306, +// socket: '/var/lib/mysql/mysql.sock', +// useSocket: false +// } + +// let opt = { +// user: opts.user || defOpts.user, +// pass: opts.pass || defOpts.pass, +// host: opts.host || defOpts.host, +// port: opts.port || defOpts.port, +// socket: opts.socket || defOpts.socket, +// useSocket: opts.useSocket || defOpts.useSocket +// }; + +// let pool = new MySQLPool(); + +// pool._host = opt.host; +// pool._password = opt.pass; +// pool._port = opt.port; +// pool._user = opt.user; +// pool._socket = opt.socket; +// pool._useSocket = opt.useSocket; + +// pool.createPool(); +// return pool +// })() + +module.exports = new MySQLPool(); \ No newline at end of file diff --git a/server-api/package.json b/server-api/package.json index 6f77f95..ec7439a 100644 --- a/server-api/package.json +++ b/server-api/package.json @@ -10,6 +10,7 @@ "koa-body": "^2.0.1", "koa-router": "^7.2.0", "koa-session": "^5.0.0", - "koa-static": "^3.0.0" + "koa-static": "^3.0.0", + "mysql": "^2.13.0" } } diff --git a/server-api/route/api/index.js b/server-api/route/api/index.js new file mode 100644 index 0000000..871a3c5 --- /dev/null +++ b/server-api/route/api/index.js @@ -0,0 +1,8 @@ +const Router = require('koa-router'); +const router = new Router(); + +router.get('/', (c, n) => { + c.body = "API Root"; +}) + +module.exports = router; \ No newline at end of file diff --git a/server-api/yarn.lock b/server-api/yarn.lock index 25e480e..9dafa84 100644 --- a/server-api/yarn.lock +++ b/server-api/yarn.lock @@ -13,6 +13,10 @@ any-promise@^1.0.0, any-promise@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" +bignumber.js@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-3.1.2.tgz#f3bdb99ad5268a15fc1f0bed2fb018e2693fe236" + bytes@2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.4.0.tgz#7d97196f9d5baf7f6935e25985549edd2a6c2339" @@ -45,6 +49,10 @@ cookies@~0.7.0: depd "~1.1.0" keygrip "~1.0.1" +core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + crc@^3.4.4: version "3.4.4" resolved "https://registry.yarnpkg.com/crc/-/crc-3.4.4.tgz#9da1e980e3bd44fc5c93bf5ab3da3378d85e466b" @@ -123,7 +131,7 @@ inflation@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/inflation/-/inflation-2.0.0.tgz#8b417e47c28f925a45133d914ca1fd389107f30f" -inherits@2.0.3: +inherits@2.0.3, inherits@~2.0.1: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" @@ -252,6 +260,14 @@ ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" +mysql@^2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/mysql/-/mysql-2.13.0.tgz#998f1f8ca46e2e3dd7149ce982413653986aae47" + dependencies: + bignumber.js "3.1.2" + readable-stream "1.1.14" + sqlstring "2.2.0" + mz@^2.3.1: version "2.6.0" resolved "https://registry.yarnpkg.com/mz/-/mz-2.6.0.tgz#c8b8521d958df0a4f2768025db69c719ee4ef1ce" @@ -308,6 +324,15 @@ raw-body@^2.2.0: iconv-lite "0.4.15" unpipe "1.0.0" +readable-stream@1.1.14: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + resolve-path@^1.3.1: version "1.3.3" resolved "https://registry.yarnpkg.com/resolve-path/-/resolve-path-1.3.3.tgz#4d83aba6468c2b8e632a575e3f52b0fa0dbe1a5c" @@ -323,10 +348,18 @@ setprototypeof@1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04" +sqlstring@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/sqlstring/-/sqlstring-2.2.0.tgz#c3135c4ea8abcd7e7ee741a4966a891d86a4f191" + "statuses@>= 1.3.1 < 2", statuses@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + thenify-all@^1.0.0: version "1.6.0" resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726"