diff --git a/.gitignore b/.gitignore index 167c2b4..f6f8872 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ ### node etc ### -secret + + work-stash # Logs diff --git a/package.json b/package.json index 8d4f3f6..0ee66be 100644 --- a/package.json +++ b/package.json @@ -8,10 +8,10 @@ "build:db": "babel ./src/db -d ./dist/db --presets es2015,stage-2,es2016 --copy-files", "build": "npm run build:db; npm run build:server", "reset:db": "babel-node ./utils/wipeDB.js", - "setup":"node ./tools/resolveGitIgnored.js;", + "setup": "node ./tools/resolveGitIgnored.js;", "docker:deploy": "npm run build; docker build -t alexcstark/carvis-api .; docker push alexcstark/carvis-api", - "start": "npm run build; node ./dist/server/index.js", - "test": "echo \"Error: no test specified\" && exit 1" + "test": "mocha --compilers js:babel-core/register ./tests/index.js", + "start": "npm run build; node ./dist/server/index.js" }, "repository": { "type": "git", @@ -41,17 +41,19 @@ "express": "^4.14.0", "express-session": "^1.14.0", "jwt-simple": "^0.5.0", - "knex": "^0.11.10", "lodash": "^4.15.0", "node-fetch": "^1.6.0", "passport": "^0.3.2", "passport-jwt": "^2.1.0", "passport-local": "^1.0.0", "pg": "^6.1.0", + "shelljs": "^0.7.3", "storkSQL": "^0.1.13", "twilio": "^2.9.2" }, "devDependencies": { + "chai": "^3.5.0", + "mocha": "^3.0.2", "morgan": "^1.7.0" } } diff --git a/secret/config.js b/secret/config.js new file mode 100644 index 0000000..0a1880d --- /dev/null +++ b/secret/config.js @@ -0,0 +1,30 @@ +// secret/config.js + +// Create a copy of this file called config.js and put your API keys there +module.exports = { + DB_CONFIG_OBJ: { + host: 'ec2-54-225-89-110.compute-1.amazonaws.com', + password: 'oRSQ_ftv16N6j73loVMTdwgbZW', + database: 'd2f7venevnjv5t', + port: 5432, + user: 'ecogqyqjcbbetg', + ssl: true + }, + UBER_SERVER_TOKEN: 'pG-f76yk_TFCTMHtYHhY7xUfLVwmt9u-l4gmgiHE', + GOOGLE_PLACES_API_KEY: 'AIzaSyDlX18NHXJ27_aZaXfpuABKe4B_ysOcoPA', + LYFT_BEARER_TOKEN: 'gAAAAABXqkmC1umTQbXVia0xRwloEZkq1ljy5eT1Mk2VfTuE6iMqkWeRDiTBXEmhlNuFUTpwJLu6zbEeRoACqnfp_uFZnpGAEROwnIm3nvV8QLAJD0jrGBGk8ErUgyMlytHXpJ0-cup_3aSv1TH3or368C34grkfSIkN3xbnrH7u6MsQMvHUXN8VJi8xbUNaMLK1Y9HMA51NXApOxhGUan2ZDTqop9UM2A==', + LYFT_USER_ID: 'gC8NlVZa847Y:PB3nRSO6pvd6SqV_85yr_hC-wgIDL0e-', + twilioCredentials: { + accountSid: 'ACbec44eaea12e629b07ccc6f5a8371836', + authToken: 'a3adbdb1e299c34ef0ac11e8cc859bfd' + }, + CARVIS_API: '54.183.205.82', + CARVIS_API_KEY: 'o2h3nrkjSDfQ@#rjlks2$TASjdfs', + USER_ENCRYPT: '239823jf' +}; + +/* +LYFT_BEARER_TOKEN currently hardcoded, needs to be updated every 86400 seconds. +TODO: update dynamically: +-- for updating one has to use the `refreshBearerToken` function from './../src/server/utils/lyft-helper.js'. +*/ diff --git a/src/db/User.js b/src/db/User.js index 57a809d..2965db1 100644 --- a/src/db/User.js +++ b/src/db/User.js @@ -1,5 +1,5 @@ import db from './db'; -import {USER_ENCRYPT} from '../../secret/config'; + export const UserSchema = function (user) { user.increments('id') .primary(); @@ -53,7 +53,7 @@ export const UserSchema = function (user) { export const User = db.model('users', { secureFields: { - password: USER_ENCRYPT, + password: process.env.USER_ENCRYPT || require('../../secret/config').USER_ENCRYPT, fields: ['lyftToken', 'lyftPaymentInfo', 'uberPassword', 'uberToken', 'password', 'alexaUserId'] } }); diff --git a/src/db/db.js b/src/db/db.js index fb51722..729db6d 100644 --- a/src/db/db.js +++ b/src/db/db.js @@ -1,5 +1,5 @@ -const DB_CONFIG_OBJ = require('../../secret/config').DB_CONFIG_OBJ; import Stork from 'storkSQL'; +const DB_CONFIG_OBJ = process.env.DB_CONFIG_JSON ? JSON.parse(DB_CONFIG_JSON) : require('../../secret/config').DB_CONFIG_OBJ; const dbConnection = new Stork(DB_CONFIG_OBJ, 'pg'); export default dbConnection; diff --git a/src/server/models/Ride.js b/src/server/models/Ride.js index 549eae9..2c8ef36 100644 --- a/src/server/models/Ride.js +++ b/src/server/models/Ride.js @@ -2,7 +2,7 @@ import { Ride } from '../../db/Ride'; import { User } from '../../db/User'; var fetch = require('node-fetch'); -var config = require('../../../../carvis/carvis-web/secret/config.js'); +// var config = require('../../secret/config.js'); var lyfthelper = require('./../utils/lyft-helper.js'); var uberhelper = require('./../utils/uber-helper.js'); diff --git a/src/server/models/User.js b/src/server/models/User.js index a2c9813..147331c 100644 --- a/src/server/models/User.js +++ b/src/server/models/User.js @@ -36,3 +36,9 @@ export const updateOrCreateUser = (req, res) => { .then((user) => res.json(user)) .catch((err) => res.json(err)); }; + +export const deleteUser = (req, res) => { + User.remove({id: req.params.userid}) + .then((user) => res.json(user)) + .catch((err) => res.json(err)); +}; diff --git a/src/server/routes.js b/src/server/routes.js index 1abbe7e..997751f 100644 --- a/src/server/routes.js +++ b/src/server/routes.js @@ -1,5 +1,5 @@ import {getUserDashboardData, updateUserData, createUser, - getAllUserData, findOrCreateUser, updateOrCreateUser } from './models/User'; + getAllUserData, findOrCreateUser, updateOrCreateUser, deleteUser } from './models/User'; import {getRidesForUser, addRide, updateRide, getAllRideData, deleteRide} from './models/Ride'; import passport from 'passport'; // import passportService from './services/passport'; @@ -8,6 +8,10 @@ import hasValidAPIToken from './server-configuration/hasValidAPIToken'; export default function(app) { // TODO only let the user with that ID find users (middleware); + app.get('/', (req, res) => { + res.status(200).send('Welcome to the Carvis API.'); + }); + app.get('/users/:userid', getUserDashboardData); app.get('/dev/users', hasValidAPIToken, getAllUserData); @@ -20,6 +24,8 @@ export default function(app) { app.put('/users/update/:userid', updateUserData); + app.delete('/dev/users/:userid', deleteUser); + app.get('/dev/rides', getAllRideData); app.get('/rides/user/:userid', getRidesForUser); diff --git a/src/server/server-configuration/config.js b/src/server/server-configuration/config.js index 81b8b3b..a5fadbd 100644 --- a/src/server/server-configuration/config.js +++ b/src/server/server-configuration/config.js @@ -5,14 +5,13 @@ import bodyParser from 'body-parser'; import cookieParser from 'cookie-parser'; import cors from 'cors'; import morgan from 'morgan'; -import config from '../../../secret/config'; export const PORT = process.env.PORT || 8080; // note: different from carvis-web export const configureServer = function (app) { app.use(express.static(path.join(__dirname, '/../../client'))); app.use(express.static(path.join(__dirname, '/../../../node_modules'))); - // app.use(cookieParser()); + app.use(cookieParser()); app.use(cors()); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); @@ -21,6 +20,5 @@ export const configureServer = function (app) { resave: true, saveUninitialized: true })); - app.set('tokenSecret', config.secret); app.use(morgan('dev')); }; diff --git a/src/server/server-configuration/hasValidAPIToken.js b/src/server/server-configuration/hasValidAPIToken.js index 7e2771f..41f2a09 100644 --- a/src/server/server-configuration/hasValidAPIToken.js +++ b/src/server/server-configuration/hasValidAPIToken.js @@ -1,9 +1,9 @@ -import {CARVIS_API_KEY} from '../../../secret/config'; +const API_KEY = process.env.CARVIS_API_KEY ? process.env.CARVIS_API_KEY : require('../../../secret/config').CARVIS_API_KEY; export default function(req, res, next) { console.log('checking validity'); const token = req.body.token || req.query.token || req.headers['x-access-token'] || null; - if (CARVIS_API_KEY.indexOf(token) >= 0) { + if (API_KEY.indexOf(token) >= 0) { next(); console.log('this is valid!'); } else { diff --git a/src/server/utils/lyft-helper.js b/src/server/utils/lyft-helper.js index cc589bc..c919ef4 100644 --- a/src/server/utils/lyft-helper.js +++ b/src/server/utils/lyft-helper.js @@ -1,12 +1,12 @@ var fetch = require('node-fetch'); var btoa = require('btoa'); -var lyftMethods = require('./lyftPrivateMethods'); -var auth = require('./../../../secret/config.js') +var lyftMethods = !process.env.TRAVIS ? require('./lyftPrivateMethods') : null; +var APItoken = !process.env.TRAVIS ? require('../../../secret/config.js') + .CARVIS_API_KEY : null; +var APIserver = !process.env.TRAVIS ? require('../../../secret/config.js') + .CARVIS_API : null; +var auth = process.env.LYFT_USER_ID || require('../../../secret/config.js') .LYFT_USER_ID; -var APItoken = require('./../../../secret/config.js') - .CARVIS_API_KEY; -var APIserver = require('./../../../secret/config.js') - .CARVIS_API; var baseURL = 'https://api.lyft.com/v1/'; // on which path is added. var refreshBearerToken = function () { diff --git a/src/server/utils/twilioHelper.js b/src/server/utils/twilioHelper.js index 831be39..03f11a8 100644 --- a/src/server/utils/twilioHelper.js +++ b/src/server/utils/twilioHelper.js @@ -1,4 +1,4 @@ -var twilioCredentials = require('../../../secret/config.js').twilioCredentials; +var twilioCredentials = JSON.parse(process.env.twilioCredentials) || require('../../../secret/config.js').twilioCredentials; var client = require('twilio')(twilioCredentials.accountSid, twilioCredentials.authToken); // NOTE: Twilio will only work with approved numbers on the free trial account, for now Chris' number is approved. diff --git a/src/server/utils/uber-helper.js b/src/server/utils/uber-helper.js index 04beff4..591961a 100644 --- a/src/server/utils/uber-helper.js +++ b/src/server/utils/uber-helper.js @@ -1,10 +1,10 @@ var fetch = require('node-fetch'); -var uberMethods = require('./uberPrivateMethods'); -var APItoken = require('./../../../secret/config.js') - .CARVIS_API_KEY; -var APIserver = require('./../../../secret/config.js') - .CARVIS_API; -var baseURL = 'https://cn-sjc1.uber.com'; +var uberMethods = !process.env.TRAVIS ? require('./uberPrivateMethods') : null; +var baseURL = 'https://cn-sjc1.uber.com'; // https ? +var APItoken = !process.env.TRAVIS ? require('../../../secret/config.js') + .CARVIS_API_KEY : null; +var APIserver = !process.env.TRAVIS ? require('../../../secret/config.js') + .CARVIS_API : null; var login = function (username, password) { var path = baseURL + uberMethods.login.path; diff --git a/tests/index.js b/tests/index.js index e471444..83ad0e7 100644 --- a/tests/index.js +++ b/tests/index.js @@ -1,5 +1,73 @@ -describe('test carvis api', () => { +const assert = require('chai').assert; +const axios = require('axios'); +const server = require('./testServer'); +let currentListeningServer; + +describe('API server', function () { + before(function () { + currentListeningServer = server.default.listen(3030); + }); + + after(function () { + currentListeningServer.close(); + }); + + describe('Check basic build', function () { + it('should return 200', function (done) { + axios.get('http://localhost:3030/') + .then((res) => { + assert.equal(res.status, 200, 'did not return 200', res.status); + done(); + }); + }); + + describe('Check restful routes', function () { + + it('should get all users when presented with the API access token', function (done) { + axios.get('http://localhost:3030/dev/users', { + headers: {'x-access-token': process.env.CARVIS_API_KEY || require('../secret/config').CARVIS_API_KEY} + }) + .then((res) => { + assert.equal(res.status, 200, 'did not return 200', res.status); + done(); + }); + }); + + let testUserId; + + it('should allow a developer to add a user when presented with the right access token', function (done) { + axios.post('http://localhost:3030/dev/users', {email: 'testy@gmail.com', password: 'test'}, { + headers: {'x-access-token': process.env.CARVIS_API_KEY || require('../secret/config').CARVIS_API_KEY} + }) + .then((res) => { + testUserId = res.data[0].id; + assert.equal(res.status, 200, 'did not return 200', res.status); + done(); + }); + }); + + it('should users to update their information', function (done) { + axios.put(`http://localhost:3030/users/update/${testUserId}`, {email: 'testy@gmail.com', password: 'newtest'}, { + }) + .then((res) => { + assert.equal(res.status, 200, 'did not return 200', res.status); + done(); + }); + }); + + + it('should delete the user created by the developer', function (done) { + axios.delete(`http://localhost:3030/dev/users/${testUserId}`, { + headers: {'x-access-token': process.env.CARVIS_API_KEY || require('../secret/config').CARVIS_API_KEY} + }) + .then((res) => { + assert.equal(res.status, 200, 'did not return 200', res.status); + done(); + }); + }); + + }); + }); - }); diff --git a/tests/testServer.js b/tests/testServer.js new file mode 100644 index 0000000..2b812cf --- /dev/null +++ b/tests/testServer.js @@ -0,0 +1,11 @@ +import express from 'express'; +import { PORT, configureServer } from '../src/server/server-configuration/config'; +import routes from '../src/server/routes'; + +const app = express(); +// Sessions, passport, auth middleware +configureServer(app); +// Set up routes +routes(app); + +export default app; diff --git a/tools/resolveGitIgnored.js b/tools/resolveGitIgnored.js index d075408..5887a56 100644 --- a/tools/resolveGitIgnored.js +++ b/tools/resolveGitIgnored.js @@ -3,6 +3,8 @@ const path = require('path'); const shell = require('shelljs'); const PRIVATE_DIR = path.join(__dirname, '/../../carvis-private-info'); +console.log(PRIVATE_DIR); +makePrivateDirsIfNeeded(); let fileDirectory = fs.readdirSync(PRIVATE_DIR); updatePrivateDirectory(fileDirectory); fileDirectory = fileDirectory.filter((file) => file[0] !== '.'); @@ -17,16 +19,23 @@ fileDirectory.forEach((file) => { fs.createReadStream(currentFile).pipe(fs.createWriteStream(path.join(__dirname, `/../${filePath}`))); }); - -function updatePrivateDirectory(directory) { - let pwd = shell.pwd(); - if (directory.length === 0) { +function makePrivateDirsIfNeeded() { + let searchDir = path.join(__dirname, '/../../'); + let thisDir = path.join(__dirname, '/../'); + if (fs.readdirSync(thisDir).indexOf('secret') === -1) { + shell.exec('mkdir secret'); + } + if (fs.readdirSync(searchDir).indexOf('carvis-private-info') === -1) { shell.cd('..'); shell.exec('git clone https://github.com/alexcstark/carvis-private-info.git'); + shell.exec('git remote add upstream https://github.com/alexcstark/carvis-private-info.git'); shell.cd('carvis-private-info'); - } else { - shell.cd('../carvis-private-info'); } - shell.exec('git pull upstream master'); +} +function updatePrivateDirectory(directory) { + console.log(directory); + let pwd = shell.pwd(); + shell.cd('../carvis-private-info'); + shell.exec('git pull origin master'); shell.cd(pwd); }