diff --git a/.env.dev b/.env.dev index e15ce3f..59ebe05 100644 --- a/.env.dev +++ b/.env.dev @@ -1,4 +1,4 @@ -PORT=3000 +PORT=4000 NODE_ENV=development JWT_SECRET=thisismysupersecrettokenjustkidding DATABASE_URL=mongodb://localhost:27017/donut-development diff --git a/app.js b/app.js index b2ebcdb..dbf77b1 100644 --- a/app.js +++ b/app.js @@ -9,13 +9,26 @@ const indexRouter = require('./app/routes/index') const authRouter = require('./app/routes/auth') const usersRouter = require('./app/routes/user') const postRouter = require('./app/routes/post') - +const passport = require('passport') +const cors = require('cors'); const app = express() +const session = require('express-session'); + +app.use( + session({ + secret: "OAuth Session", + saveUninitialized: true, + resave: true + }) +); + +app.use(cors()); // view engine setup app.set('views', path.join(__dirname, 'views')) app.set('view engine', 'ejs') +app.use(passport.initialize()); app.use(logger('dev')) app.use(express.json()) app.use(express.urlencoded({ extended: false })) diff --git a/app/models/User.js b/app/models/User.js index 5ce1bbd..149c7e4 100644 --- a/app/models/User.js +++ b/app/models/User.js @@ -28,7 +28,6 @@ const UserSchema = new mongoose.Schema( password: { type: String, trim: true, - required: true, minlength: 6, validate (password) { if (password.toLowerCase().includes('password')) { @@ -60,6 +59,14 @@ const UserSchema = new mongoose.Schema( trim: true, maxlength: 300 }, + provider: { + type: String, + trim: true + }, + providerID:{ + type: String, + trim: true + }, tokens: [{ token: { type: String, diff --git a/app/routes/index.js b/app/routes/index.js index 741fddc..108fe0b 100644 --- a/app/routes/index.js +++ b/app/routes/index.js @@ -1,9 +1,38 @@ var express = require('express') var router = express.Router() +const passport = require('passport') +const authPassport = require('../../config/authPassport'); const documentationUrl = 'https://documenter.getpostman.com/view/1159934/SWDze1Rp' + +authPassport(passport); + /* GET home page. */ router.get('/', function (req, res, next) { res.redirect(documentationUrl) }) +router.get('/auth/google', passport.authenticate('google', { + scope: ['https://www.googleapis.com/auth/userinfo.profile', 'https://www.googleapis.com/auth/userinfo.email'] +})); + +router.get('/auth/google/callback', + passport.authenticate('google', { + failureRedirect: 'http://localhost:3000' + }), + (req, res) => { + res.redirect('http://localhost:3000/dashboard'); + } +); + +router.get('/auth/github', + passport.authenticate('github', { scope: [ 'user:email' ] })); + +router.get('/auth/github/callback', + passport.authenticate('github', { + failureRedirect: 'http://localhost:3000' + }), + (req, res) => { + res.redirect('http://localhost:3000/dashboard'); + }); + module.exports = router diff --git a/config/authPassport.js b/config/authPassport.js new file mode 100644 index 0000000..c24e71e --- /dev/null +++ b/config/authPassport.js @@ -0,0 +1,57 @@ +const GoogleStrategy = require('passport-google-oauth').OAuth2Strategy; +const GitHubStrategy = require('passport-github2').Strategy; +const configAuth = require('./authTokens'); +const User = require('../app/models/User') + + +module.exports = function(passport) { + passport.serializeUser(function(user, done) { + done(null, user.id); + }); + + passport.deserializeUser(function(id, done) { + User.findById(id, function(err, user) { + done(err, user); + }); + }); + + passport.use(new GoogleStrategy({ + clientID : configAuth.googleAuth.clientID, + clientSecret : configAuth.googleAuth.clientSecret, + callbackURL : configAuth.googleAuth.callbackURL, + }, + function(accessToken, refreshToken, profile, done) { + User.findOne({email: profile.emails[0].value}, async function(err,user){ + if(!user){ + const user = new User(); + user.name = profile.displayName; + user.provider = profile.provider; + user.providerID = profile.id; + user.email = profile.emails[0].value; + user.save() + } + return done(err, user); + }) + } + )); + passport.use(new GitHubStrategy({ + clientID : configAuth.githubAuth.clientID, + clientSecret : configAuth.githubAuth.clientSecret, + callbackURL : configAuth.githubAuth.callbackURL, + }, + async function(accessToken, refreshToken, profile, done) { + User.findOne({email: profile.emails[0].value}, async function(err,user){ + if(!user){ + const user = new User(); + user.name = profile.displayName; + user.provider = profile.provider; + user.providerID = profile.id; + user.email = profile.emails[0].value; + user.save() + } + return done(err, user); + }) + } + )); + +}; diff --git a/config/authTokens.js b/config/authTokens.js new file mode 100644 index 0000000..13bf270 --- /dev/null +++ b/config/authTokens.js @@ -0,0 +1,12 @@ +module.exports = { + 'githubAuth' : { + 'clientID' : process.env.GITHUBCLIENTID, + 'clientSecret' : process.env.GITHUBSECRET, + 'callbackURL' : 'http://localhost:4000/auth/github/callback' + }, + 'googleAuth' : { + 'clientID' : process.env.GOOGLECLIENTID, + 'clientSecret' : process.env.GOOGLECLIENTSECRET, + 'callbackURL' : 'http://localhost:4000/auth/google/callback' + } +}; \ No newline at end of file diff --git a/config/passport.js b/config/passport.js deleted file mode 100644 index a2bb829..0000000 --- a/config/passport.js +++ /dev/null @@ -1,2 +0,0 @@ -// TODO: -// YET TO IMPLEMENT WITH PASSPORT diff --git a/package.json b/package.json index e36a4b2..5148345 100644 --- a/package.json +++ b/package.json @@ -12,12 +12,17 @@ "bcrypt": "^3.0.6", "body-parser": "^1.19.0", "cookie-parser": "~1.4.4", + "cors": "^2.8.5", "debug": "~2.6.9", "ejs": "~2.6.1", "express": "^4.16.4", + "express-session": "^1.17.0", "jsonwebtoken": "^8.5.1", "mongoose": "^5.7.7", "morgan": "^1.9.1", + "passport": "^0.4.1", + "passport-github2": "^0.1.11", + "passport-google-oauth": "^2.0.0", "validator": "^10.11.0" }, "jest": {