From a7f39f31da6d5b1a215cf3b8fbbb5b81b26e0bb8 Mon Sep 17 00:00:00 2001 From: sharabesh Date: Mon, 11 Feb 2019 08:20:22 -0500 Subject: [PATCH] social-oauth update gitignore oauth-server-configured --- .gitignore | 3 ++ api/config/config.example.js | 30 +++++++++++ api/routes/userAuth.js | 79 ++++++++++++++++++++++++++++ api/utils/passport.js | 75 +++++++++++++++++++++++++++ package-lock.json | 99 +++++++++++++++++++++++++----------- package.json | 2 + 6 files changed, 257 insertions(+), 31 deletions(-) diff --git a/.gitignore b/.gitignore index 0692bf4..4585c26 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,6 @@ storage/* npm-debug.log !/storage/codes/default/ docker +.idea +package-lock.json +pa diff --git a/api/config/config.example.js b/api/config/config.example.js index 8c1574b..d22b8f1 100644 --- a/api/config/config.example.js +++ b/api/config/config.example.js @@ -11,6 +11,16 @@ const config = { event_key: 'somekey', }, sendgridAPIKey: 'key', + facebook: { + client_id: 'YOUR APP ID', + client_secret: 'YOUR APP SECRET', + callback_url: '{API URL}/user/callback/facebook', + }, + google: { + client_id: 'YOUR APP ID', + client_secret: 'YOUR APP SECRET', + callback_url: '{API URL}/user/callback/google', + }, }, production: { app: { @@ -24,6 +34,16 @@ const config = { event_key: 'somekey', }, sendgridAPIKey: 'key', + facebook: { + client_id: 'YOUR APP ID', + client_secret: 'YOUR APP SECRET', + callback_url: '{API URL}/user/callback/facebook', + }, + google: { + client_id: 'YOUR APP ID', + client_secret: 'YOUR APP SECRET', + callback_url: '{API URL}/user/callback/google', + }, }, test: { app: { @@ -37,6 +57,16 @@ const config = { event_key: 'somekey', }, sendgridAPIKey: 'key', + facebook: { + client_id: 'YOUR APP ID', + client_secret: 'YOUR APP SECRET', + callback_url: '{API URL}/user/callback/facebook', + }, + google: { + client_id: 'YOUR APP ID', + client_secret: 'YOUR APP SECRET', + callback_url: '{API URL}/user/callback/google', + }, }, }; const env = process.env.NODE_ENV || 'development'; diff --git a/api/routes/userAuth.js b/api/routes/userAuth.js index 3cfd4f1..c0dc353 100644 --- a/api/routes/userAuth.js +++ b/api/routes/userAuth.js @@ -16,6 +16,11 @@ const isLoggedIn = require('../middlewares/isLoggedIn'); const router = express.Router(); +router.use((req, res, next) => { + req.session.socketId = req.query.socketId; + next(); +}); + router.post('/register', [ check('username') .not().isEmpty().withMessage('Username cannot be empty') @@ -238,4 +243,78 @@ router.get('/verify/:username/:tokenSource', async (req, res) => { return res.status(400).redirect('https://code.pragyan.org'); }); +router.get('/auth/google', (req, res, next) => { + passport.authenticate('google', { scope: 'https://www.googleapis.com/auth/plus.login' }, () => null)(req, res, next); +}); + +router.get('/callback/google', (req, res, next) => { + passport.authenticate('google', { failureRedirect: '/' }, (err, user, info) => { + if (err) { + return res.status(500).json({ + type: 'Error', + error: err, + }); + } + if (!user) { + return res.status(400).json({ + type: 'Error', + error: info, + }); + } + req.logIn(user, (error) => { + if (error) { + return res.status(500).json({ + type: 'Error', + error: 'Internal server error', + }); + } + res.cookie('userId', user.id); + socket.sendMessage(user.id, + { + isLoggedIn: true, username: user.username, email: user.email, country: 'IN', + }, + 'google'); + return res.end(); + }); + return null; + })(req, res, next); +}); + +router.get('/auth/facebook', (req, res, next) => { + passport.authenticate('facebook', { scope: ['id', 'email', 'public_profile', 'user_location'] }, () => null)(req, res, next); +}); + +router.get('/callback/facebook', (req, res, next) => { + passport.authenticate('facebook', { failureRedirect: '/' }, (err, user, info) => { + if (err) { + return res.status(500).json({ + type: 'Error', + error: 'Internal server error', + }); + } + if (!user) { + return res.status(400).json({ + type: 'Error', + error: info, + }); + } + req.logIn(user, (error) => { + if (error) { + return res.status(500).json({ + type: 'Error', + error: 'Internal server error', + }); + } + res.cookie('userId', user.id); + socket.sendMessage(user.id, + { + isLoggedIn: true, username: user.username, email: user.email, country: user.country, + }, + 'facebook'); + return res.end(); + }); + return null; + })(req, res, next); +}); + module.exports = router; diff --git a/api/utils/passport.js b/api/utils/passport.js index 778f518..9884b4d 100644 --- a/api/utils/passport.js +++ b/api/utils/passport.js @@ -2,13 +2,47 @@ const LocalStrategy = require('passport-local').Strategy; const bcrypt = require('bcrypt'); const Sequelize = require('sequelize'); const rp = require('request-promise'); +const FacebookStrategy = require('passport-facebook').Strategy; +const GoogleStrategy = require('passport-google-oauth2').Strategy; const codeStatus = require('../models').codestatus; const git = require('../utils/gitHandlers'); const User = require('../models').user; const config = require('../config/config.js'); + const { Op } = Sequelize; +const registerSocial = (user, callback) => { + User.findOne( + { email: user.email }, + ) + .then((existingUser) => { + if (existingUser) { + return callback(null, existingUser, 'Success'); + } + const passwordHash = bcrypt.hash(user.id, 10); + return User.create({ + username: user.email, + fullname: user.name, + email: user.email, + password: passwordHash, + country: 'IN', + }) + .then((createdUser) => { + git.createUserDir(createdUser.username) + .then(() => { + codeStatus.create({ + userId: createdUser.id, + latestSrcPath: `${git.getUserDir(createdUser.username)}/code.cpp`, + }); + }); + return callback(null, createdUser, 'Success'); + }) + .catch(err => callback(err)); + }) + .catch(err => callback(err)); +}; + module.exports = (passport) => { passport.use(new LocalStrategy( ((email, password, done) => { @@ -80,4 +114,45 @@ module.exports = (passport) => { done(error, null); }); }); + passport.use(new FacebookStrategy( + { + clientID: config.facebook.client_id, + clientSecret: config.facebook.client_secret, + callbackURL: config.facebook.callback_url, + profileFields: ['id', 'displayName', 'email'], + passReqToCallback: true, + }, + async (req, accessToken, refreshToken, profile, done) => { + const data = await JSON.stringify(profile); + registerSocial( + { + id: data.id, + name: data.name, + email: data.email, + country: data.location.country || 'IN', + }, + done, + ); + }, + )); + passport.use(new GoogleStrategy( + { + clientID: config.google.client_id, + clientSecret: config.google.client_secret, + callbackURL: config.google.callback_url, + passReqToCallback: true, + }, + async (req, accessToken, refreshToken, profile, done) => { + const data = await JSON.stringify(profile); + registerSocial( + { + id: data.id, + name: data.name, + email: data.email, + country: data.country || 'IN', + }, + done, + ); + }, + )); }; diff --git a/package-lock.json b/package-lock.json index 0df745f..b86f266 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1011,7 +1011,7 @@ "dependencies": { "callsites": { "version": "2.0.0", - "resolved": "http://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", "dev": true } @@ -1033,7 +1033,7 @@ }, "callsites": { "version": "0.2.0", - "resolved": "http://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", "dev": true }, @@ -1466,7 +1466,7 @@ }, "d": { "version": "1.0.0", - "resolved": "http://registry.npmjs.org/d/-/d-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", "dev": true, "requires": { @@ -1975,7 +1975,7 @@ "dependencies": { "doctrine": { "version": "1.5.0", - "resolved": "http://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", "dev": true, "requires": { @@ -2409,7 +2409,7 @@ }, "finalhandler": { "version": "1.1.1", - "resolved": "http://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", "requires": { "debug": "2.6.9", @@ -3175,7 +3175,7 @@ }, "got": { "version": "6.7.1", - "resolved": "http://registry.npmjs.org/got/-/got-6.7.1.tgz", + "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", "dev": true, "requires": { @@ -3312,7 +3312,7 @@ }, "http-errors": { "version": "1.6.3", - "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", "requires": { "depd": "~1.1.2", @@ -3580,7 +3580,7 @@ }, "is-accessor-descriptor": { "version": "0.1.6", - "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { @@ -3641,7 +3641,7 @@ }, "is-data-descriptor": { "version": "0.1.4", - "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { @@ -3763,7 +3763,7 @@ }, "is-obj": { "version": "1.0.1", - "resolved": "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", "dev": true }, @@ -4009,7 +4009,7 @@ }, "load-json-file": { "version": "2.0.0", - "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", "dev": true, "requires": { @@ -4106,7 +4106,7 @@ }, "media-typer": { "version": "0.3.0", - "resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" }, "mem": { @@ -4201,7 +4201,7 @@ }, "minimist": { "version": "0.0.8", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", "dev": true }, @@ -4228,7 +4228,7 @@ }, "mkdirp": { "version": "0.5.1", - "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, "requires": { @@ -4345,7 +4345,7 @@ }, "named-placeholders": { "version": "1.1.1", - "resolved": "http://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.1.tgz", + "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.1.tgz", "integrity": "sha1-O3oNJiA910s6nfTJz7gnsvuQfmQ=", "requires": { "lru-cache": "2.5.0" @@ -4353,7 +4353,7 @@ "dependencies": { "lru-cache": { "version": "2.5.0", - "resolved": "http://registry.npmjs.org/lru-cache/-/lru-cache-2.5.0.tgz", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.5.0.tgz", "integrity": "sha1-2COIrpyWC+y+oMc7uet5tsbOmus=" } } @@ -4395,7 +4395,7 @@ }, "next-tick": { "version": "1.0.0", - "resolved": "http://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", "dev": true }, @@ -4482,6 +4482,11 @@ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", "dev": true }, + "oauth": { + "version": "0.9.15", + "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", + "integrity": "sha1-vR/vr2hslrdUda7VGWQS/2DPucE=" + }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -4622,7 +4627,7 @@ }, "os-homedir": { "version": "1.0.2", - "resolved": "http://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true }, @@ -4639,7 +4644,7 @@ }, "os-tmpdir": { "version": "1.0.2", - "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, @@ -4752,6 +4757,22 @@ "pause": "0.0.1" } }, + "passport-facebook": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/passport-facebook/-/passport-facebook-3.0.0.tgz", + "integrity": "sha512-K/qNzuFsFISYAyC1Nma4qgY/12V3RSLFdFVsPKXiKZt434wOvthFW1p7zKa1iQihQMRhaWorVE1o3Vi1o+ZgeQ==", + "requires": { + "passport-oauth2": "1.x.x" + } + }, + "passport-google-oauth2": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/passport-google-oauth2/-/passport-google-oauth2-0.1.6.tgz", + "integrity": "sha1-39cBasdEn+J8/rJSrpdK/CMleg0=", + "requires": { + "passport-oauth2": "^1.1.2" + } + }, "passport-local": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/passport-local/-/passport-local-1.0.0.tgz", @@ -4760,6 +4781,17 @@ "passport-strategy": "1.x.x" } }, + "passport-oauth2": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/passport-oauth2/-/passport-oauth2-1.4.0.tgz", + "integrity": "sha1-9i+BWDy+EmCb585vFguTlaJ7hq0=", + "requires": { + "oauth": "0.9.x", + "passport-strategy": "1.x.x", + "uid2": "0.0.x", + "utils-merge": "1.x.x" + } + }, "passport-strategy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", @@ -4779,7 +4811,7 @@ }, "path-is-absolute": { "version": "1.0.1", - "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "path-is-inside": { @@ -4831,7 +4863,7 @@ }, "pify": { "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true }, @@ -4992,7 +5024,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true } @@ -5027,7 +5059,7 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "requires": { "core-util-is": "~1.0.0", @@ -5177,7 +5209,7 @@ }, "require-uncached": { "version": "1.0.3", - "resolved": "http://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", "dev": true, "requires": { @@ -5270,7 +5302,7 @@ }, "safe-regex": { "version": "1.1.0", - "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "dev": true, "requires": { @@ -5853,7 +5885,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "requires": { "safe-buffer": "~5.1.0" @@ -5876,7 +5908,7 @@ }, "strip-eof": { "version": "1.0.0", - "resolved": "http://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", "dev": true }, @@ -6104,7 +6136,7 @@ }, "through": { "version": "2.3.8", - "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", "dev": true }, @@ -6261,6 +6293,11 @@ "random-bytes": "~1.0.0" } }, + "uid2": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz", + "integrity": "sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I=" + }, "umzug": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/umzug/-/umzug-2.2.0.tgz", @@ -6519,7 +6556,7 @@ }, "wrap-ansi": { "version": "2.1.0", - "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", "dev": true, "requires": { @@ -6544,7 +6581,7 @@ }, "string-width": { "version": "1.0.2", - "resolved": "http://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { @@ -6555,7 +6592,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { diff --git a/package.json b/package.json index 003839c..a9c422e 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,8 @@ "moment": "^2.24.0", "mysql2": "1.6.4", "passport": "0.4.0", + "passport-facebook": "^3.0.0", + "passport-google-oauth2": "^0.1.6", "passport-local": "1.0.0", "randomstring": "1.1.5", "request": "^2.88.0",