├── README.md ├── app └── routes.js ├── certificate.crt ├── config ├── database.js └── passport.js ├── model └── dbconnection.js ├── package.json ├── privateKey.key ├── routes ├── REST_DELETE.js ├── REST_EDIT.js ├── REST_GET.js └── REST_POST.js ├── scripts └── create_database.js └── server.js /README.md: -------------------------------------------------------------------------------- 1 | # Node-MySQL-Rest-API-Passport-JWT 2 | Simple RESTful API implementation on Node.js + Express + MySQL + Passport + JWT 3 | 4 | REST API for CRUD operations with database using Node.js and Express.js framework with MySQL. For access control this project use Passport.js and JSON Web Token. 5 | 6 | # Running project 7 | 8 | You need to have installed Node.js and MySQL on your local machine. 9 | 10 | ## Install dependencies 11 | 12 | To install dependencies enter project folder and run following command: 13 | 14 | `npm install` 15 | 16 | 17 | ## Setting up local MySQL database 18 | 19 | First edit `/model/dbconnection.js` and `/config/database.js` to add your username and password and database for your local MySQL database. 20 | 21 | To create user table for Passport signup and login, run `node scripts/create_database.js 22 | 23 | ## To run server execute: 24 | 25 | `node server.js` 26 | 27 | ## License 28 | 29 | MIT 30 | -------------------------------------------------------------------------------- /app/routes.js: -------------------------------------------------------------------------------- 1 | module.exports = function(app, passport, SERVER_SECRET) { 2 | 3 | // default message 4 | app.get('/', function (req, res) { 5 | res.send('

Welcome to the database

'); 6 | }); 7 | 8 | // =========== authenticate login info and generate access token =============== 9 | 10 | app.post('/login', function(req, res, next) { 11 | passport.authenticate('local-login', function(err, user, info) { 12 | if (err) { return next(err); } 13 | // stop if it fails 14 | if (!user) { return res.json({ message: 'Invalid Username of Password' }); } 15 | 16 | req.logIn(user, function(err) { 17 | // return if does not match 18 | if (err) { return next(err); } 19 | 20 | // generate token if it succeeds 21 | const db = { 22 | updateOrCreate: function(user, cb){ 23 | cb(null, user); 24 | } 25 | }; 26 | db.updateOrCreate(req.user, function(err, user){ 27 | if(err) {return next(err);} 28 | // store the updated information in req.user again 29 | req.user = { 30 | id: user.username 31 | }; 32 | }); 33 | 34 | // create token 35 | const jwt = require('jsonwebtoken'); 36 | req.token = jwt.sign({ 37 | id: req.user.id, 38 | }, SERVER_SECRET, { 39 | expiresIn: 120 40 | }); 41 | 42 | // lastly respond with json 43 | return res.status(200).json({ 44 | user: req.user, 45 | token: req.token 46 | }); 47 | }); 48 | })(req, res, next); 49 | }); 50 | 51 | // ============================================================================= 52 | 53 | // ==================== Allows users to create accounts ======================== 54 | 55 | app.post('/signup', passport.authenticate('local-signup', { 56 | successRedirect : '/signup/successjson', 57 | failureRedirect : '/signup/failurejson', 58 | failureFlash : true 59 | })); 60 | // return messages for signup users 61 | app.get('/signup/successjson', function(req, res) { 62 | res.json({ message: 'Successfully created user' }); 63 | }); 64 | 65 | app.get('/signup/failurejson', function(req, res) { 66 | res.json({ message: 'This user already exists' }); 67 | }); 68 | 69 | // ============================================================================= 70 | 71 | // ================= Protected APIs for authenticated Users ==================== 72 | 73 | // get tools and routes 74 | var expressJwt = require('express-jwt'), 75 | REST_POST = require('../routes/REST_POST'), 76 | REST_GET = require('../routes/REST_GET'), 77 | REST_EDIT = require('../routes/REST_EDIT'), 78 | REST_DELETE = require('../routes/REST_DELETE'); 79 | 80 | // authenticate access token 81 | const authenticate = expressJwt({secret : SERVER_SECRET}); 82 | 83 | // GET, EndPoint: 84 | // https://127.0.0.1:5000/product/api/all?order={orderby} 85 | app.get('/product/api/get/all', authenticate, REST_GET.getAllRecords); 86 | 87 | // GET, Endpoint: 88 | // https://127.0.0.1:5000/product/api/?c={target_column}&q={target_value}&order={orderby} 89 | app.get('/product/api/get', authenticate, REST_GET.findByColumn); 90 | 91 | // GET, EndPoint: 92 | // https://127.0.0.1:5000/product/api/search/?c={target_column}&start={start}&end={end}&order={orderby} 93 | app.get('/product/api/get/search', authenticate, REST_GET.rangeSearch); 94 | 95 | // POST, Endpoint: 96 | // https://127.0.0.1:5000/product/api/add/?content=1,2,3... 97 | app.post('/product/api/add', authenticate, REST_POST.addOne); 98 | 99 | // POST, Endpoint: 100 | // https://127.0.0.1:5000/product/api/add/?content[0]=1,2,3,...&content[1]=1,2,3... 101 | app.post('/product/api/add/batch/', authenticate, REST_POST.addBatch); 102 | 103 | // EDIT, Endpoint: 104 | // https://127.0.0.1:5000/product/api/edit/:orderID/?content={} 105 | app.post('/product/api/edit/:id', authenticate, REST_EDIT); 106 | 107 | // Endpoint: https://127.0.0.1:5000/product/api/delete/?id={orderID} 108 | app.delete('/product/api/delete/', authenticate, REST_DELETE); 109 | 110 | // ============================================================================= 111 | 112 | } 113 | -------------------------------------------------------------------------------- /certificate.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDxTCCAq2gAwIBAgIJAIQ8So5xicl2MA0GCSqGSIb3DQEBCwUAMHkxCzAJBgNV 3 | BAYTAlVTMQswCQYDVQQIDAJXQTEQMA4GA1UEBwwHU2VhdHRsZTELMAkGA1UECgwC 4 | QlgxCjAIBgNVBAsMATExDDAKBgNVBAMMA1NhbTEkMCIGCSqGSIb3DQEJARYVYmlj 5 | aGVuZ3h1MDFAZ21haWwuY29tMB4XDTE3MDgyMjAyMDIxM1oXDTE4MDgyMjAyMDIx 6 | M1oweTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdTZWF0dGxl 7 | MQswCQYDVQQKDAJCWDEKMAgGA1UECwwBMTEMMAoGA1UEAwwDU2FtMSQwIgYJKoZI 8 | hvcNAQkBFhViaWNoZW5neHUwMUBnbWFpbC5jb20wggEiMA0GCSqGSIb3DQEBAQUA 9 | A4IBDwAwggEKAoIBAQCsCTw+AxPwftgwxFfiovi5GP2d/hBrIsoUisDbSO8+bFgz 10 | pH8axPkz/0S0g2Erl1lrozmiTlUAF6DQqWHDV6JocES8VFh8S2+iC1tCpWO8BMkm 11 | WG9+IdlOHLI2Zbsv+JmXr0TBHwOfGQ11yEDyISsXaZJoUIDUDFD/jZmFnvX2HpIi 12 | KBqJkDMGZn+xHeZ/JymLjoRbWUBzoXhgK+joTx3u8wd0ODPoaeiik7LWep5oYAIy 13 | 73vGXyMJe6oPlHPzNVht0WtxU/Z8jzK+28puXltSzPfxjvnpwrpo98GRt9rEr/S6 14 | ncKFFc24gPens9DLxG1iNUF6qLAclGdpUEVtFcynAgMBAAGjUDBOMB0GA1UdDgQW 15 | BBTNvucaXjdiCRrQi0HwK+w2CKs8szAfBgNVHSMEGDAWgBTNvucaXjdiCRrQi0Hw 16 | K+w2CKs8szAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAVwoCBAcq2 17 | +cOHDJzhx8L+H7iEOZ55PV6DWrGj+WSTtgV6nj/P3DXsxMm2tk2LKWZlAcqN2nJ5 18 | u1cr4LKR/gVOPrnZG0itTNz/9Jd1P4L8HYfbEIMfO+FibLyfRGy7BB411mP1X17c 19 | XYLYXXuHfPX4ck8OWACGAYKKB3lfRe6ndiAKf4HEmDFflbpcX1RUat6fWzvZDJOT 20 | Y/VhtZd6xevH5gIVQKkhKhZXCeCx/UfKP0NlCfT55q3qSngxTXu6RPPPaq3mXVwC 21 | o7Med/APbw/RI6MRBBn4ZzyFoOwm5tc6cnLO1uveeodq7Ioujk7rK/eQu1oCjteM 22 | YmFQ7zwBNt0N 23 | -----END CERTIFICATE----- 24 | -------------------------------------------------------------------------------- /config/database.js: -------------------------------------------------------------------------------- 1 | // config/database.js 2 | module.exports = { 3 | 'connection': { 4 | 'host': 'localhost', 5 | 'user': 'root', 6 | 'password': '123456' 7 | }, 8 | 'database': 'excelData', 9 | 'users_table': 'users' 10 | }; 11 | -------------------------------------------------------------------------------- /config/passport.js: -------------------------------------------------------------------------------- 1 | // load all the things needed 2 | var LocalStrategy = require('passport-local').Strategy; 3 | 4 | // load up the user model 5 | var mysql = require('mysql'); 6 | var bcrypt = require('bcrypt'); 7 | var dbconfig = require('./database'); 8 | var connection = mysql.createConnection(dbconfig.connection); 9 | 10 | connection.query('USE ' + dbconfig.database); 11 | 12 | module.exports = function(passport) { 13 | 14 | // passport set up; required for persistent login sessions 15 | // passport needs ability to serialize and unserialize users out of session 16 | 17 | // used to serialize the user for the session 18 | passport.serializeUser(function(user, done) { 19 | done(null, user.id); 20 | }); 21 | 22 | // used to deserialize the user 23 | passport.deserializeUser(function(id, done) { 24 | connection.query("SELECT * FROM users WHERE id = ? ",[id], function(err, rows){ 25 | done(err, rows[0]); 26 | }); 27 | }); 28 | 29 | // handles signup 30 | passport.use( 31 | 'local-signup', 32 | new LocalStrategy({ 33 | usernameField : 'username', 34 | passwordField : 'password', 35 | passReqToCallback : true 36 | }, 37 | function(req, username, password, done) { 38 | connection.query("SELECT * FROM users WHERE username = ?",[username], function(err, rows) { 39 | if (err) 40 | return done(err); 41 | if (rows.length) { 42 | return done(null, false, req.flash('signupMessage', 'That username is already taken.')); 43 | } else { 44 | 45 | // if there is no user with that username then create the user 46 | 47 | var newUserMysql = { 48 | username: username, 49 | password: bcrypt.hashSync(password, bcrypt.genSaltSync(10)) // use the generateHash function in our user model 50 | }; 51 | 52 | var insertQuery = "INSERT INTO users ( username, password ) values (?,?)"; 53 | 54 | connection.query(insertQuery,[newUserMysql.username, newUserMysql.password],function(err, rows) { 55 | newUserMysql.id = rows.insertId; 56 | 57 | return done(null, newUserMysql); 58 | }); 59 | } 60 | }); 61 | }) 62 | ); 63 | 64 | // handles login 65 | passport.use( 66 | 'local-login', 67 | new LocalStrategy({ 68 | usernameField : 'username', 69 | passwordField : 'password', 70 | passReqToCallback : true 71 | }, 72 | function(req, username, password, done) { 73 | connection.query("SELECT * FROM users WHERE username = ?",[username], function(err, rows){ 74 | if (err) 75 | return done(err); 76 | if (!rows.length) { 77 | return done(null, false, req.flash('loginMessage', 'No user found.')); 78 | } 79 | 80 | // if the user is found but the password is wrong 81 | if (!bcrypt.compareSync(password, rows[0].password)) 82 | return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.')); 83 | 84 | // all is well, return successful user 85 | return done(null, rows[0]); 86 | }); 87 | }) 88 | ); 89 | }; 90 | -------------------------------------------------------------------------------- /model/dbconnection.js: -------------------------------------------------------------------------------- 1 | var mysql = require('mysql'); 2 | 3 | var connection = mysql.createConnection({ 4 | host : 'localhost', 5 | user : 'root', 6 | password : '123456', 7 | database : 'excelData' 8 | }); 9 | 10 | try { 11 | connection.connect(); 12 | console.log('Connected to the MYSQL database'); 13 | 14 | } catch(e) { 15 | console.log('Database Connetion failed:' + e); 16 | } 17 | 18 | module.exports = connection; 19 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "internship-project-demo", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "bcrypt": "^1.0.3", 10 | "body-parser": "^1.17.2", 11 | "connect-flash": "^0.1.1", 12 | "cookie-parser": "^1.4.3", 13 | "cors": "^2.8.4", 14 | "debug": "~2.6.3", 15 | "ejs": "^2.5.7", 16 | "express": "^4.15.4", 17 | "express-jwt": "^5.3.0", 18 | "express-session": "^1.15.5", 19 | "fs": "0.0.1-security", 20 | "https": "^1.0.0", 21 | "jade": "~1.11.0", 22 | "jsonwebtoken": "^7.4.3", 23 | "morgan": "^1.8.2", 24 | "mysql": "^2.14.1", 25 | "passport": "^0.4.0", 26 | "passport-http-bearer": "^1.0.1", 27 | "passport-local": "^1.0.0", 28 | "path": "^0.12.7", 29 | "serve-favicon": "~2.4.2" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /privateKey.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCsCTw+AxPwftgw 3 | xFfiovi5GP2d/hBrIsoUisDbSO8+bFgzpH8axPkz/0S0g2Erl1lrozmiTlUAF6DQ 4 | qWHDV6JocES8VFh8S2+iC1tCpWO8BMkmWG9+IdlOHLI2Zbsv+JmXr0TBHwOfGQ11 5 | yEDyISsXaZJoUIDUDFD/jZmFnvX2HpIiKBqJkDMGZn+xHeZ/JymLjoRbWUBzoXhg 6 | K+joTx3u8wd0ODPoaeiik7LWep5oYAIy73vGXyMJe6oPlHPzNVht0WtxU/Z8jzK+ 7 | 28puXltSzPfxjvnpwrpo98GRt9rEr/S6ncKFFc24gPens9DLxG1iNUF6qLAclGdp 8 | UEVtFcynAgMBAAECggEATyhUssfhxdfni9DcC2knfqu0Dp1XWqSATSFnCb8ubg+W 9 | KfT3kw6tB7LeHx0QeelC+Nb67uaSD9/PXBOD60kIbnux9OHucQqYy/vjuu+0y098 10 | aotoiaXzghCMI6F9lt4RdgzsWtv1Y6A4ZEiHMaH3XOdzuVHJZUhhgKTbzfLNg7fe 11 | KJC1D8uEsIS9kdMmtmGJHK2HuN6eI2g4z40hwbH7xDk4rOf3tB6ZqOcOv7Fk0dEt 12 | CfX0q2J96v6lH8/gxQOlSMDUoEYnyxE+BsonNVLsUQR8QakepGosAMwrNeNEPNPr 13 | 7Jus0yV6VGm7xp6pKLLFe8KCIdEOXGnGDUst2C/CaQKBgQDVasFYK+IohqnwMIXZ 14 | e39SAhw32t60/rAVC1v8KP5DmVYIZJJ2aaqJ2bHjdDjVCAm5B5kmVM9JTBIgRwdE 15 | BRkjIS12oTe/mu4mzGfNZi83DpOyxRwDd9phdi/1smJl3fxKgQpDGlOj5ZOwlDps 16 | JFPBpy/zk9VkCN95vUlwhrEl/QKBgQDOXMKti6U5jkirh536/JLEUstXbKcjzwNd 17 | 6rybz2fUd2jywBQh0qv/yILMhDjeSuazkREN6I612/g2FPLAFQ5tYJ+qeEEo9Ozk 18 | C9ogEGAYUoNfWppm9bmm3W+8KpjwOhewo3F6C3HQom0NErCADhY/d+LUWL52ZsiY 19 | NTka6NdscwKBgQCUkyqhMIPVBNMgBRfZ7XEY7aEpfXUX+kspi2vxY7SH6SMM2r9g 20 | MnXoXCbMm6fJHzxtlQ2YsuhQNeZUlD5Jq2bxnvJgqSH/gWOUnS8SvrXWFY7boP+8 21 | pl7hBP+khBiepGk0kRtM1fIuovAruTXm/W9V3Qe0AlJHvymdPhr3fL2tHQKBgChv 22 | AnIQn5IUb+a0Dt9Dp9oxwsfhcSpSAH3hZY096UE3GGgf/JHX/n2CoyZBbgcYM/XR 23 | Ib9Q5s15STwHhLzgI1CJEx/KqjHFM7lHHTkVHE8Hs9f2H7S2xuaMEr2Stx6yszuX 24 | +r8ICQfxG17pX43ntLJA4j/rF36JixpPq127a6JDAoGAbdzm1SBwZnGKxu8sfp8f 25 | ObwWFm+RZSssNj72uIOK/rmcWXgRGv36qdFovhKr7zeT85SjQJmEx3TI0YDNlQAm 26 | ewABR6tTPofjd+0PmJAkrtrxdMvC1NZZpt+h3tJHs2fLT8Z61e3UxCIsjHtoz97r 27 | GRhqd1hSI2qjYRsU/c19Pu0= 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /routes/REST_DELETE.js: -------------------------------------------------------------------------------- 1 | // product/api/delete/?id={orderID} 2 | module.exports = function (req,res) { 3 | var connection = require('../model/dbconnection'); 4 | // Delete by order id 5 | var id = req.query.id; 6 | 7 | connection.query('DELETE FROM saleData WHERE Order_ID = ?', [id], function(err, result) { 8 | if (!err){ 9 | var response = []; 10 | 11 | if (result.affectedRows != 0) { 12 | response.push({'result' : 'success'}); 13 | } else { 14 | response.push({'msg' : 'No Result Found'}); 15 | } 16 | 17 | res.setHeader('Content-Type', 'application/json'); 18 | res.status(200).send(JSON.stringify(response)); 19 | } else { 20 | res.status(400).send(err); 21 | } 22 | }); 23 | }; 24 | -------------------------------------------------------------------------------- /routes/REST_EDIT.js: -------------------------------------------------------------------------------- 1 | // product/api/edit/:orderID/?content={} 2 | module.exports = function (req,res) { 3 | var connection = require('../model/dbconnection'); 4 | var response = []; 5 | 6 | // split content in the url to arrays 7 | var arr = req.query.content.split(','); 8 | 9 | // Make sure required content is provided 10 | if ( 11 | typeof req.params.id !== 'undefined' && 12 | arr.length == 21 13 | ) { 14 | 15 | // Pair content with column 16 | var id = req.params.id; 17 | var content = { 18 | Row_ID: arr[0], // Order_ID cannot be edited 19 | Order_Date: arr[2], 20 | Order_Priority: arr[3], 21 | Order_Quantity: arr[4], 22 | Sales: arr[5], 23 | Discount: arr[6], 24 | Ship_Mode: arr[7], 25 | Profit: arr[8], 26 | Unit_Price: arr[9], 27 | Shipping_Cost: arr[10], 28 | Customer_Name: arr[11], 29 | Province: arr[12], 30 | Region: arr[13], 31 | Customer_Segment: arr[14], 32 | Product_Category: arr[15], 33 | Product_Sub_Category: arr[16], 34 | Product_Name: arr[17], 35 | Product_Container: arr[18], 36 | Product_Base_Margin: arr[19], 37 | Ship_Date: arr[20] 38 | }; 39 | 40 | connection.query('UPDATE saleData SET ? WHERE Order_ID = ?', [content, id], 41 | function(err, result) { 42 | if (!err){ 43 | 44 | if (result.affectedRows != 0) { 45 | response.push({'result' : 'success'}); 46 | } else { 47 | response.push({'msg' : 'No Result Found'}); 48 | } 49 | 50 | res.setHeader('Content-Type', 'application/json'); 51 | res.status(200).send(JSON.stringify(response)); 52 | } else { 53 | res.status(400).send(err); 54 | } 55 | }); 56 | 57 | } else { 58 | response.push({'result' : 'error', 'msg' : 'Please fill required information'}); 59 | res.setHeader('Content-Type', 'application/json'); 60 | res.send(200, JSON.stringify(response)); 61 | } 62 | }; 63 | -------------------------------------------------------------------------------- /routes/REST_GET.js: -------------------------------------------------------------------------------- 1 | // Given a certain column and target value, get records 2 | // product/api/get/?c={target_column}&q={target_value}&order={orderby} 3 | exports.findByColumn = function (req,res) { 4 | var connection = require('../model/dbconnection'); 5 | var column = req.query.c; 6 | var val = req.query.q; 7 | 8 | // If order not speficied, then use order date 9 | if (typeof req.query.order == 'undefined') 10 | { 11 | var order = 'Order_Date'; 12 | } else { 13 | var order = req.query.order; 14 | } 15 | 16 | // get value of limit 17 | if (typeof req.query.limit == 'undefined') 18 | { 19 | var limit = 100; 20 | } else { 21 | var limit = parseInt(req.query.limit); 22 | } 23 | 24 | if (limit > 500 || limit < 1) { 25 | limit = 100; 26 | } 27 | 28 | // get offset value from requested page 29 | if (typeof req.query.page == 'undefined') 30 | { 31 | var page = 1; 32 | } else { 33 | var page = parseInt(req.query.page); 34 | } 35 | 36 | var offset = limit * (page - 1); 37 | 38 | connection.query('SELECT * from saleData where ?? = ? ORDER BY ?? DESC LIMIT ? OFFSET ?', 39 | [ column, val, order, limit, offset ], function(err, rows, fields) { 40 | if (!err){ 41 | var response = []; 42 | 43 | if (rows.length != 0) { 44 | response.push({'result' : 'success', 'data' : rows}); 45 | } else { 46 | response.push({'result' : 'error', 'msg' : 'No Results Found'}); 47 | } 48 | 49 | res.setHeader('Content-Type', 'application/json'); 50 | res.status(200).send(JSON.stringify(response)); 51 | } else { 52 | res.status(400).send(err); 53 | } 54 | }); 55 | }; 56 | 57 | // Get all records 58 | // product/api/get/all?order={orderby} 59 | exports.getAllRecords = function (req,res) { 60 | var connection = require('../model/dbconnection'); 61 | var val = req.query.q; 62 | 63 | // If order not speficied, then use order date 64 | if (typeof req.query.order == 'undefined') 65 | { 66 | var order = 'Order_Date'; 67 | } else { 68 | var order = req.query.order; 69 | } 70 | 71 | // get value of limit 72 | if (typeof req.query.limit == 'undefined') 73 | { 74 | var limit = 100; 75 | } else { 76 | var limit = parseInt(req.query.limit); 77 | } 78 | 79 | if (limit > 500 || limit < 1) { 80 | limit = 100; 81 | } 82 | 83 | // get offset value from requested page 84 | if (typeof req.query.page == 'undefined') 85 | { 86 | var page = 1; 87 | } else { 88 | var page = parseInt(req.query.page); 89 | } 90 | 91 | var offset = limit * (page - 1); 92 | 93 | connection.query('SELECT * from saleData ORDER BY ?? DESC LIMIT ? OFFSET ?', 94 | [ order, limit, page ], function(err, rows, fields) { 95 | if (!err){ 96 | var response = []; 97 | 98 | if (rows.length != 0) { 99 | response.push({'result' : 'success', 'data' : rows}); 100 | } else { 101 | response.push({'result' : 'error', 'msg' : 'No Results Found'}); 102 | } 103 | 104 | res.setHeader('Content-Type', 'application/json'); 105 | res.status(200).send(JSON.stringify(response)); 106 | } else { 107 | res.status(400).send(err); 108 | } 109 | }); 110 | }; 111 | 112 | // Given a certain column and a range of values, get records in range 113 | // product/api/get/search/?c={target_column}&s={start}&e={end}&order={orderby} 114 | exports.rangeSearch = function (req,res) { 115 | var connection = require('../model/dbconnection'); 116 | var column = req.query.c; 117 | var startVal = req.query.s; 118 | var endVal = req.query.e; 119 | 120 | // If order not speficied, then use order date 121 | if (typeof req.query.order == 'undefined') 122 | { 123 | var order = 'Order_Date'; 124 | } else { 125 | var order = req.query.order; 126 | } 127 | 128 | // get value of limit 129 | if (typeof req.query.limit == 'undefined') 130 | { 131 | var limit = 100; 132 | } else { 133 | var limit = parseInt(req.query.limit); 134 | } 135 | 136 | if (limit > 500 || limit < 1) { 137 | limit = 100; 138 | } 139 | 140 | // get offset value from requested page 141 | if (typeof req.query.page == 'undefined') 142 | { 143 | var page = 1; 144 | } else { 145 | var page = parseInt(req.query.page); 146 | } 147 | 148 | var offset = limit * (page - 1); 149 | 150 | connection.query('SELECT * from saleData WHERE ?? > ? AND ?? < ? ORDER BY ?? DESC LIMIT ? OFFSET ?', 151 | [ column, startVal, column, endVal, order, limit, offset ], function(err, rows, fields) { 152 | if (!err){ 153 | var response = []; 154 | 155 | if (rows.length != 0) { 156 | response.push({'result' : 'success', 'data' : rows}); 157 | } else { 158 | response.push({'result' : 'error', 'msg' : 'No Results Found'}); 159 | } 160 | 161 | res.setHeader('Content-Type', 'application/json'); 162 | res.status(200).send(JSON.stringify(response)); 163 | } else { 164 | res.status(400).send(err); 165 | } 166 | }); 167 | }; 168 | -------------------------------------------------------------------------------- /routes/REST_POST.js: -------------------------------------------------------------------------------- 1 | // product/api/add/?content=1,2,3,... 2 | exports.addOne = function (req,res) { 3 | var connection = require('../model/dbconnection'); 4 | var response = []; 5 | 6 | // split content in the url to arrays 7 | var arr = req.query.content.split(','); 8 | 9 | // make sure all required fields are provided 10 | if ( 11 | typeof req.query.content !== 'undefined' && 12 | arr.length == 21 13 | ) { 14 | 15 | // Pair content with column 16 | var content = { 17 | Row_ID: arr[0], 18 | Order_ID: arr[1], 19 | Order_Date: arr[2], 20 | Order_Priority: arr[3], 21 | Order_Quantity: arr[4], 22 | Sales: arr[5], 23 | Discount: arr[6], 24 | Ship_Mode: arr[7], 25 | Profit: arr[8], 26 | Unit_Price: arr[9], 27 | Shipping_Cost: arr[10], 28 | Customer_Name: arr[11], 29 | Province: arr[12], 30 | Region: arr[13], 31 | Customer_Segment: arr[14], 32 | Product_Category: arr[15], 33 | Product_Sub_Category: arr[16], 34 | Product_Name: arr[17], 35 | Product_Container: arr[18], 36 | Product_Base_Margin: arr[19], 37 | Ship_Date: arr[20] 38 | }; 39 | 40 | connection.query('INSERT INTO saleData SET ?', content, 41 | function(err, result) { 42 | if (!err){ 43 | 44 | if (result.affectedRows != 0) { 45 | response.push({'result' : 'success'}); 46 | } else { 47 | response.push({'msg' : 'No Result Found'}); 48 | } 49 | 50 | res.setHeader('Content-Type', 'application/json'); 51 | res.status(200).send(JSON.stringify(response)); 52 | } else { 53 | res.status(400).send(err); 54 | } 55 | }); 56 | 57 | } else { 58 | response.push({'result' : 'error', 'msg' : 'Please fill required details'}); 59 | res.setHeader('Content-Type', 'application/json'); 60 | res.status(200).send(JSON.stringify(response)); 61 | } 62 | }; 63 | 64 | // product/api/add/batch/?content[0]=1,2,3,...& content[1]=1,2,3... 65 | exports.addBatch = function (req,res) { 66 | var connection = require('../model/dbconnection'); 67 | var response = []; 68 | 69 | // make sure all required fields are provided 70 | if ( 71 | typeof req.query.content !== 'undefined' 72 | ) { 73 | 74 | // initial an array to store all records to insert 75 | var arr = []; 76 | // pair each record with columns 77 | for (i = 0; i < req.query.content.length; i++) { 78 | // split contents 79 | var tmpArr = req.query.content[i].split(','); 80 | var tmpContent = { 81 | Row_ID: tmpArr[0], 82 | Order_ID: tmpArr[1], 83 | Order_Date: tmpArr[2], 84 | Order_Priority: tmpArr[3], 85 | Order_Quantity: tmpArr[4], 86 | Sales: tmpArr[5], 87 | Discount: tmpArr[6], 88 | Ship_Mode: tmpArr[7], 89 | Profit: tmpArr[8], 90 | Unit_Price: tmpArr[9], 91 | Shipping_Cost: tmpArr[10], 92 | Customer_Name: tmpArr[11], 93 | Province: tmpArr[12], 94 | Region: tmpArr[13], 95 | Customer_Segment: tmpArr[14], 96 | Product_Category: tmpArr[15], 97 | Product_Sub_Category: tmpArr[16], 98 | Product_Name: tmpArr[17], 99 | Product_Container: tmpArr[18], 100 | Product_Base_Margin: tmpArr[19], 101 | Ship_Date: tmpArr[20] 102 | }; 103 | // add formated record to array 104 | arr.push(tmpContent); 105 | } 106 | 107 | connection.query('INSERT INTO saleData SET ?', arr, 108 | function(err, result) { 109 | if (!err){ 110 | 111 | if (result.affectedRows != 0) { 112 | response.push({'result' : 'success'}); 113 | } else { 114 | response.push({'msg' : 'No Result Found'}); 115 | } 116 | 117 | res.setHeader('Content-Type', 'application/json'); 118 | res.status(200).send(JSON.stringify(response)); 119 | } else { 120 | res.status(400).send(err); 121 | } 122 | }); 123 | 124 | } else { 125 | response.push({'result' : 'error', 'msg' : 'Please fill required details'}); 126 | res.setHeader('Content-Type', 'application/json'); 127 | res.status(200).send(JSON.stringify(response)); 128 | } 129 | }; 130 | -------------------------------------------------------------------------------- /scripts/create_database.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by barrett on 8/28/14. 3 | */ 4 | 5 | var mysql = require('mysql'); 6 | var dbconfig = require('../config/database'); 7 | 8 | var connection = mysql.createConnection(dbconfig.connection); 9 | 10 | connection.query('CREATE DATABASE ' + dbconfig.database); 11 | 12 | connection.query('\ 13 | CREATE TABLE `' + dbconfig.database + '`.`' + dbconfig.users_table + '` ( \ 14 | `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, \ 15 | `username` VARCHAR(20) NOT NULL, \ 16 | `password` CHAR(60) NOT NULL, \ 17 | PRIMARY KEY (`id`), \ 18 | UNIQUE INDEX `id_UNIQUE` (`id` ASC), \ 19 | UNIQUE INDEX `username_UNIQUE` (`username` ASC) \ 20 | )'); 21 | 22 | console.log('Success: Database Created!') 23 | 24 | connection.end(); 25 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | // get all the tools needed 2 | var express = require('express'); 3 | var path = require('path'); 4 | var cookieParser = require('cookie-parser'); 5 | var bodyParser = require('body-parser'); 6 | var session = require('express-session'); 7 | var morgan = require('morgan'); 8 | var app = express(); 9 | var port = process.env.PORT || 5555; 10 | var passport = require('passport'); 11 | var flash = require('connect-flash'); 12 | var fs = require('fs'); 13 | var https = require('https'); 14 | 15 | // config passport and connect to DB 16 | require('./config/passport')(passport); 17 | 18 | // set up express 19 | app.use(morgan('dev')); 20 | app.use(bodyParser.json()); 21 | app.use(bodyParser.urlencoded({ extended: false })); 22 | app.use(cookieParser()); 23 | app.use(express.static(path.join(__dirname, 'public'))); 24 | app.set('view engine', 'ejs'); 25 | 26 | // config passport 27 | app.use(session({ 28 | secret: 'vidyapathaisalwaysrunning', 29 | resave: true, 30 | saveUninitialized: true 31 | } )); // session secret 32 | app.use(passport.initialize()); 33 | app.use(passport.session()); // persistent login sessions 34 | app.use(flash()); // use connect-flash for flash messages stored in session 35 | 36 | // Set Https certificate 37 | var options = { 38 | key: fs.readFileSync('privateKey.key'), 39 | cert: fs.readFileSync('certificate.crt') 40 | }; 41 | 42 | const SERVER_SECRET = 'ohgodpleasenobug'; 43 | 44 | // routes 45 | require('./app/routes.js')(app, passport, SERVER_SECRET); // load our routes and pass in our app and fully configured passport 46 | 47 | // Create server 48 | https.createServer(options, app).listen(port, function(){ 49 | console.log('Server listening on port ' + port); 50 | }); 51 | --------------------------------------------------------------------------------