Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
StephenGrider committed Feb 6, 2017
0 parents commit 17826d6
Show file tree
Hide file tree
Showing 15 changed files with 3,508 additions and 0 deletions.
Binary file added .DS_Store
Binary file not shown.
3 changes: 3 additions & 0 deletions .babelrc
@@ -0,0 +1,3 @@
{
"presets": ["env", "react"]
}
1 change: 1 addition & 0 deletions .gitignore
@@ -0,0 +1 @@
node_modules
5 changes: 5 additions & 0 deletions client/index.html
@@ -0,0 +1,5 @@
<head>
</head>
<body>
<div id="root" />
</body>
12 changes: 12 additions & 0 deletions client/index.js
@@ -0,0 +1,12 @@
import React from 'react';
import ReactDOM from 'react-dom';

const Root = () => {
return (
<div>
Auth Starter
</div>
);
};

ReactDOM.render(<Root />, document.querySelector('#root'));
5 changes: 5 additions & 0 deletions index.js
@@ -0,0 +1,5 @@
const app = require('./server/server');

app.listen(4000, () => {
console.log('Listening');
});
41 changes: 41 additions & 0 deletions package.json
@@ -0,0 +1,41 @@
{
"name": "users",
"version": "1.0.0",
"description": "Starter pack for an auth-included graphql project",
"repository": {
"type": "git",
"url": "github.com/stephengrider"
},
"main": "index.js",
"scripts": {
"dev": "nodemon index.js --ignore client"
},
"author": "",
"license": "ISC",
"dependencies": {
"apollo-client": "^0.8.2",
"axios": "^0.15.3",
"babel-core": "^6.22.1",
"babel-loader": "^6.2.10",
"babel-preset-env": "^1.1.8",
"babel-preset-react": "^6.22.0",
"bcrypt-nodejs": "0.0.3",
"body-parser": "^1.16.0",
"connect-mongo": "^1.3.2",
"express": "^4.14.0",
"express-graphql": "^0.6.1",
"express-session": "^1.15.0",
"graphql": "^0.8.2",
"graphql-tag": "^1.2.4",
"html-webpack-plugin": "^2.26.0",
"lodash": "^4.17.4",
"mongoose": "^4.7.8",
"passport": "^0.3.2",
"passport-local": "^1.0.0",
"react": "^15.4.2",
"react-apollo": "^0.10.0",
"react-dom": "^15.4.2",
"webpack": "^2.2.0",
"webpack-dev-middleware": "^1.9.0"
}
}
1 change: 1 addition & 0 deletions server/models/index.js
@@ -0,0 +1 @@
require('./user');
31 changes: 31 additions & 0 deletions server/models/user.js
@@ -0,0 +1,31 @@
const bcrypt = require('bcrypt-nodejs');
const crypto = require('crypto');
const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const UserSchema = new Schema({
email: String,
password: String
});

UserSchema.pre('save', function save(next) {
const user = this;
if (!user.isModified('password')) { return next(); }
bcrypt.genSalt(10, (err, salt) => {
if (err) { return next(err); }
bcrypt.hash(user.password, salt, null, (err, hash) => {
if (err) { return next(err); }
user.password = hash;
next();
});
});
});


UserSchema.methods.comparePassword = function comparePassword(candidatePassword, cb) {
bcrypt.compare(candidatePassword, this.password, (err, isMatch) => {
cb(err, isMatch);
});
};

mongoose.model('user', UserSchema);
8 changes: 8 additions & 0 deletions server/schema/queries/root_query.js
@@ -0,0 +1,8 @@
const graphql = require('graphql');
const { GraphQLObjectType } = graphql;

const RootQuery = new GraphQLObjectType({
name: 'RootQueryType'
});

module.exports = RootQuery;
8 changes: 8 additions & 0 deletions server/schema/schema.js
@@ -0,0 +1,8 @@
const graphql = require('graphql');
const { GraphQLSchema } = graphql;

const RootQuery = require('./queries/root_query');

module.exports = new GraphQLSchema({
query: RootQuery
});
45 changes: 45 additions & 0 deletions server/server.js
@@ -0,0 +1,45 @@
const express = require('express');
const models = require('./models');
const expressGraphQL = require('express-graphql');
const mongoose = require('mongoose');
const session = require('express-session');
const passport = require('passport');
const passportConfig = require('./services/auth');
const bodyParser = require('body-parser');
const MongoStore = require('connect-mongo')(session);
const schema = require('./schema/schema');

const app = express();

// Replace with your mongoLab URI
const MONGO_URI = 'mongodb://stephengrider:stephengrider@ds131139.mlab.com:31139/facespace';

mongoose.Promise = global.Promise;
mongoose.connect(MONGO_URI);
mongoose.connection
.once('open', () => console.log('Connected to MongoLab instance.'))
.on('error', error => console.log('Error connecting to MongoLab:', error));

app.use(bodyParser.json());
app.use(session({
resave: true,
saveUninitialized: true,
secret: 'aaabbbccc',
store: new MongoStore({
url: MONGO_URI,
autoReconnect: true
})
}));
app.use(passport.initialize());
app.use(passport.session());
app.use('/graphql', expressGraphQL({
schema,
graphiql: true
}));

const webpackMiddleware = require('webpack-dev-middleware');
const webpack = require('webpack');
const webpackConfig = require('../webpack.config.js');
app.use(webpackMiddleware(webpack(webpackConfig)));

module.exports = app;
59 changes: 59 additions & 0 deletions server/services/auth.js
@@ -0,0 +1,59 @@
const mongoose = require('mongoose');
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;

const User = mongoose.model('user');

passport.serializeUser((user, done) => {
done(null, user.id);
});

passport.deserializeUser((id, done) => {
User.findById(id, (err, user) => {
done(err, user);
});
});

passport.use(new LocalStrategy({ usernameField: 'email' }, (email, password, done) => {
User.findOne({ email: email.toLowerCase() }, (err, user) => {
if (err) { return done(err); }
if (!user) { return done(null, false, 'Invalid Credentials'); }
user.comparePassword(password, (err, isMatch) => {
if (err) { return done(err); }
if (isMatch) {
return done(null, user);
}
return done(null, false, 'Invalid credentials.');
});
});
}));

function signup({ email, password, req }) {
const user = new User({ email, password });

return User.findOne({ email })
.then(existingUser => {
if (existingUser) { throw new Error('Email in use'); }
return user.save();
})
.then(user => {
return new Promise((resolve, reject) => {
req.logIn(user, (err) => {
if (err) { reject(err); }
resolve(user);
});
});
});
}

function login({ email, password, req }) {
return new Promise((resolve, reject) => {
passport.authenticate('local', (err, user) => {
if (!user) { reject('Invalid credentials.') }

req.login(user, () => resolve(user));
})({ body: { email, password } });
});
}

module.exports = { signup, login };
24 changes: 24 additions & 0 deletions webpack.config.js
@@ -0,0 +1,24 @@
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
entry: './client/index.js',
output: {
path: '/',
filename: 'bundle.js'
},
module: {
rules: [
{
use: 'babel-loader',
test: /\.js$/,
exclude: /node_modules/
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: 'client/index.html'
})
]
};

0 comments on commit 17826d6

Please sign in to comment.