Skip to content

Commit

Permalink
resolve merge
Browse files Browse the repository at this point in the history
  • Loading branch information
alexcstark committed Aug 16, 2016
2 parents e9b5aa6 + e705ca9 commit 111bc9c
Show file tree
Hide file tree
Showing 8 changed files with 200 additions and 94 deletions.
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# carvis-api
Pithy project description

##Team

Built by `@alexcstark`, `@cpruijsen`, `@daredia`, `@JasonArkens17` as our final project `@hackreactor` .

##Stack:
Built using Node, Express, Passport, [StorkSQL](https://www.npmjs.com/package/storkSQL)

##Deployment:
Docker, AWS EC2, Build tools: NPM scripting, Webpack, ESlint. Testing: TravisCI, Mocha, Chai.

##APIs:
Uber, Lyft, Google Places, Twilio.

###Installing Dependencies

From within the root directory:

`npm install`

##Moving Forward

From here you will need to link to the [Carvis-web](https://github.com/complex-joins/carvis). Also this repo does not include any of the Alexa skill side of the project. For Alexa skill go [here](https://github.com/complex-joins/alexa-poc)

Contributing

See CONTRIBUTING.md for contribution guidelines.
25 changes: 16 additions & 9 deletions src/server/controllers/authentication.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,36 @@ import User from '../models/User';
// import config from '../jwtconfig';

function tokenForUser(user) {
const timestamp = new Date().getTime();
const timestamp = new Date()
.getTime();
return jwt.encode({ sub: user.id, iat: timestamp }, config.secret);
}

exports.signin = function(req, res, next) {
exports.signin = function (req, res, next) {
// User has already had their email and password auth'd
// We just need to give them a token
res.send({ token: tokenForUser(req.user) });
};

exports.signup = function(req, res, next) {
exports.signup = function (req, res, next) {
const email = req.body.email;
const password = req.body.password;

if (!email || !password) {
return res.status(422).send({ error: 'You must provide email and password'});
return res.status(422)
.send({ error: 'You must provide email and password' });
}

// See if a user with the given email exists
User.findOne({ email: email }, function(err, existingUser) {
if (err) { return next(err); }
User.findOne({ email: email }, function (err, existingUser) {
if (err) {
return next(err);
}

// If a user with email does exist, return an error
if (existingUser) {
return res.status(422).send({ error: 'Email is in use' });
return res.status(422)
.send({ error: 'Email is in use' });
}

// If a user with email does NOT exist, create and save user record
Expand All @@ -36,8 +41,10 @@ exports.signup = function(req, res, next) {
password: password
});

user.save(function(err) {
if (err) { return next(err); }
user.save(function (err) {
if (err) {
return next(err);
}

// Repond to request indicating the user was created
res.json({ token: tokenForUser(user) });
Expand Down
73 changes: 43 additions & 30 deletions src/server/models/Ride.js
Original file line number Diff line number Diff line change
@@ -1,65 +1,78 @@
import { Ride } from '../../db/Ride';
import { User } from '../../db/User';

var lyfthelper = require('../utils/lyft-helper.js');
var uberhelper = require('../utils/uber-helper.js');
var fetch = require('node-fetch');
// var config = require('../../secret/config.js');
var lyfthelper = require('./../utils/lyft-helper.js');
var uberhelper = require('./../utils/uber-helper.js');

export const addRide = function (req, res) {
var rideId;

export const addRide = function (req, res) {
Ride.create(req.body)
.then((ride) => {
rideId = ride.id; // is there a cleaner way to do this?
return res.json(ride);
ride = ride[0];
console.log(ride);

let vendor = ride.winner;
let rideId = ride.id;
let origin = {
lat: ride.originLat,
lng: ride.originLng,
routableAddress: ride.originRoutableAddress
};
let destination = {
lat: ride.destinationLat,
lng: ride.destinationLng,
routableAddress: ride.destinationRoutableAddress
};
let partySize = ride.partySize || 1;

// carvisUserId -- to query the user table for tokens etc.
let userId = ride.userId;

// let dbURL = 'http://' + config.CARVIS_API + '/users/' + userId;
let dbURL = 'http://localhost:8080/users/' + userId;
console.log('pre db get', vendor, userId, dbURL, rideId);

return getUserAndRequestRide(dbURL, origin, destination, partySize, rideId, vendor)
})
.catch((err) => res.json(err)); // add catch for errors.
};

const getUserAndRequestRide = function (dbURL, origin, destination, partySize, rideId, vendor) {

let vendor = req.body.winner;
let origin = {
lat: req.body.originLat,
lng: req.body.originLng,
routableAddress: originRoutableAddress
};
let destination = {
lat: req.body.destinationLat,
lng: req.body.destinationLng,
routableAddress: req.body.destinationRoutableAddress
};
let partySize = req.body.partySize || 1;

// carvisUserId -- to query the user table for tokens etc.
let userId = req.body.userId;
let dbURL = 'http://54.183.205.82/users' + userId;

return fetch(dbURL, {
fetch(dbURL, {
method: 'GET',
headers: {
'Content-Type': 'application/json'
// 'x-access-token': config.CARVIS_API_KEY
}
})
.then(function (res) {
return res.json();
})
.then(function (data) {
console.log('success fetching user from DB', data);
// console.log('success fetching user from DB', data); // pre-decrypt.
data = User.decryptModel(data[0]); // decrypt the tokens to pass to vendor

if (vendor === 'Uber') {
let token = data.uberToken;
return uberhelper.confirmPickup(origin, token, destination);
let token = data[0].uberToken;
uberhelper.confirmPickup(origin, token, destination);

} else if (vendor === 'Lyft') {
let lyftPaymentInfo = data.lyftPaymentInfo;
let lyftToken = data.lyftToken;
return lyfthelper.getCost(lyftToken, origin, destination, lyftPaymentInfo, partySize, rideId);
console.log('token post decrypt', lyftToken); // works!

lyfthelper.getCost(lyftToken, origin, destination, lyftPaymentInfo, partySize, rideId);

} else {
console.warn('not a valid vendor - check stacktrace');
return; // return a 404.
}
})
.catch(function (err) {
console.warn('error fetching user from db', err);
});

};

export const getRidesForUser = function (req, res) {
Expand Down
4 changes: 2 additions & 2 deletions src/server/server-configuration/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import cookieParser from 'cookie-parser';
import cors from 'cors';
import morgan from 'morgan';

export const PORT = process.env.PORT || 8000;
export const PORT = process.env.PORT || 8080; // note: different from carvis-web

export const configureServer = function(app) {
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());
Expand Down
42 changes: 15 additions & 27 deletions src/server/services/passport.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,28 @@ import passport from 'passport';
import User from '../models/User';
// import jwtconfig from '../jwtconfig';
import LocalStrategy from 'passport-local';
import {Strategy as JwtStrategy} from 'passport-jwt';
import {ExtractJwt} from 'passport-jwt';

const localOptions = { usernnameField: 'email' };
const localLogin = new LocalStrategy(localOptions, function(email, password, done) {
User.findOrCreateUser({ email: email }, function(err, user) {
if (err) { return done(err); }
if (!user) { return done(null, false); }
const localLogin = new LocalStrategy(localOptions, function (email, password, done) {
User.findOrCreateUser({ email: email }, function (err, user) {
if (err) {
return done(err);
}
if (!user) {
return done(null, false);
}

user.isValidPassword(password, function(err, isMatch) {
if (err) { return done(err); }
if (!isMatch) { return done(null, false); }
user.isValidPassword(password, function (err, isMatch) {
if (err) {
return done(err);
}
if (!isMatch) {
return done(null, false);
}

return done(null, user);
});
});
});

const jwtOptions = {
jwtFromRequest: ExtractJwt.fromHeader('authorization'),
secretOrKey: jwtconfig.secret
};

const jwtLogin = new JwtStrategy(jwtOptions, function(payload, done) {
User.findById(payload.sub, function(err, user) {
if (err) { return done(err, false); }

if (user) {
done(null, user);
} else {
done(null, false);
}
});
});

passport.use(jwtLogin);
passport.use(localLogin);
35 changes: 22 additions & 13 deletions src/server/utils/lyft-helper.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
var fetch = require('node-fetch');
var btoa = require('btoa');
var lyftMethods = !process.env.TRAVIS ? require('./lyftPrivateMethods') : null;
var auth = process.env.LYFT_USER_ID || require('../../../secret/config.js').LYFT_USER_ID;
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 baseURL = 'https://api.lyft.com/v1/'; // on which path is added.

// TODO: database posts in each response -- with generic key naming.

var refreshBearerToken = function () {
var url = 'https://api.lyft.com/oauth/token';
var headers = {
Expand Down Expand Up @@ -85,12 +88,14 @@ var lyftPhoneCodeAuth = function (fourDigitCode, phoneNumber, userLocation, user
var response = lyftMethods.phoneCodeAuth.responseMethod(data, userId);

// POST THE USER DATA TO OUR RELATIONAL DATABASE
var dbpostURL = 'http://54.183.205.82/users/updateOrCreate';
// var dbpostURL = 'http://' + APIserver + '/users/updateOrCreate';
var dbpostURL = 'http://localhost:8080/users/updateOrCreate';

fetch(dbpostURL, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
'Content-Type': 'application/json',
'x-access-token': APItoken
},
body: JSON.stringify(response)
})
Expand All @@ -110,10 +115,8 @@ var lyftPhoneCodeAuth = function (fourDigitCode, phoneNumber, userLocation, user
});
};

// origin {startLat, startLng, startAddress}
// destination {endLat, endLng, endAddress}
var getCost = function (token, origin, destination, paymentInfo, partySize, rideId) {
var url = baseURL + lyftMethods.getCost.path(origin, destination);
var url = lyftMethods.getCost.path(origin, destination);
var headers = lyftMethods.getCost.headers(token);

fetch(url, {
Expand All @@ -124,7 +127,7 @@ var getCost = function (token, origin, destination, paymentInfo, partySize, ride
return res.json();
})
.then(function (data) {
console.log('successful getCost post LYFT', data);
console.log('successful getCost LYFT', data);
var response = lyftMethods.getCost.responseMethod(data);

// random time 1-5 seconds - to simulate more 'natural' patterns
Expand All @@ -134,16 +137,19 @@ var getCost = function (token, origin, destination, paymentInfo, partySize, ride
}, time);
})
.catch(function (err) {
console.log('error post of getCost LYFT', err);
console.log('error getCost LYFT', err);
});

};

var requestRide = function (token, costToken, destination, origin, paymentInfo, partySize, rideId, tripDuration) {
var url = baseURL + lyftMethods.requestRide.path;
var url = lyftMethods.requestRide.path;
var headers = lyftMethods.requestRide.headers(token);
var body = lyftMethods.requestRide.body(costToken, destination, origin, paymentInfo, partySize);

console.log('costToken pre requestRide', costToken);
console.log('body pre requestRide', body);

fetch(url, {
method: 'POST',
headers: headers,
Expand All @@ -155,14 +161,17 @@ var requestRide = function (token, costToken, destination, origin, paymentInfo,
.then(function (data) {
console.log('successful requestRide post LYFT', data);
var response = lyftMethods.requestRide.responseMethod(data, userId, tripDuration);
var dbpostURL = 'http://54.183.205.82/rides/' + rideId;

// var dbpostURL = 'http://' + APIserver + '/rides/' + rideId;
var dbpostURL = 'http://localhost:8080/rides/' + rideId;

// once we receive the request-ride confirmation response
// we update the DB record for that ride with eta and vendorRideId
fetch(dbpostURL, {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
'Content-Type': 'application/json',
'x-access-token': APItoken
},
body: JSON.stringify(response)
})
Expand Down
Loading

0 comments on commit 111bc9c

Please sign in to comment.