| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012 |
- /**
- * Satellizer Node.js Example
- * (c) 2015 Sahat Yalkabov
- * License: MIT
- */
- var path = require('path');
- var qs = require('querystring');
- var async = require('async');
- var bcrypt = require('bcryptjs');
- var bodyParser = require('body-parser');
- var colors = require('colors');
- var cors = require('cors');
- var express = require('express');
- var logger = require('morgan');
- var jwt = require('jwt-simple');
- var moment = require('moment');
- var mongoose = require('mongoose');
- var request = require('request');
- var config = require('./config');
- var userSchema = new mongoose.Schema({
- email: { type: String, unique: true, lowercase: true },
- password: { type: String, select: false },
- displayName: String,
- picture: String,
- bitbucket: String,
- facebook: String,
- foursquare: String,
- google: String,
- github: String,
- instagram: String,
- linkedin: String,
- live: String,
- yahoo: String,
- twitter: String,
- twitch: String
- });
- userSchema.pre('save', function(next) {
- var user = this;
- if (!user.isModified('password')) {
- return next();
- }
- bcrypt.genSalt(10, function(err, salt) {
- bcrypt.hash(user.password, salt, function(err, hash) {
- user.password = hash;
- next();
- });
- });
- });
- userSchema.methods.comparePassword = function(password, done) {
- bcrypt.compare(password, this.password, function(err, isMatch) {
- done(err, isMatch);
- });
- };
- var User = mongoose.model('User', userSchema);
- mongoose.connect(config.MONGO_URI);
- mongoose.connection.on('error', function(err) {
- console.log('Error: Could not connect to MongoDB. Did you forget to run `mongod`?'.red);
- });
- var app = express();
- app.set('port', process.env.NODE_PORT || 3000);
- app.set('host', process.env.NODE_IP || 'localhost');
- app.use(cors());
- app.use(logger('dev'));
- app.use(bodyParser.json());
- app.use(bodyParser.urlencoded({ extended: true }));
- // Force HTTPS on Heroku
- if (app.get('env') === 'production') {
- app.use(function(req, res, next) {
- var protocol = req.get('x-forwarded-proto');
- protocol == 'https' ? next() : res.redirect('https://' + req.hostname + req.url);
- });
- }
- app.use(express.static(path.join(__dirname, '../../client')));
- /*
- |--------------------------------------------------------------------------
- | Login Required Middleware
- |--------------------------------------------------------------------------
- */
- function ensureAuthenticated(req, res, next) {
- if (!req.header('Authorization')) {
- return res.status(401).send({ message: 'Please make sure your request has an Authorization header' });
- }
- var token = req.header('Authorization').split(' ')[1];
- var payload = null;
- try {
- payload = jwt.decode(token, config.TOKEN_SECRET);
- }
- catch (err) {
- return res.status(401).send({ message: err.message });
- }
- if (payload.exp <= moment().unix()) {
- return res.status(401).send({ message: 'Token has expired' });
- }
- req.user = payload.sub;
- next();
- }
- /*
- |--------------------------------------------------------------------------
- | Generate JSON Web Token
- |--------------------------------------------------------------------------
- */
- function createJWT(user) {
- var payload = {
- sub: user._id,
- iat: moment().unix(),
- exp: moment().add(14, 'days').unix()
- };
- return jwt.encode(payload, config.TOKEN_SECRET);
- }
- /*
- |--------------------------------------------------------------------------
- | GET /api/me
- |--------------------------------------------------------------------------
- */
- app.get('/api/me', ensureAuthenticated, function(req, res) {
- User.findById(req.user, function(err, user) {
- res.send(user);
- });
- });
- /*
- |--------------------------------------------------------------------------
- | PUT /api/me
- |--------------------------------------------------------------------------
- */
- app.put('/api/me', ensureAuthenticated, function(req, res) {
- User.findById(req.user, function(err, user) {
- if (!user) {
- return res.status(400).send({ message: 'User not found' });
- }
- user.displayName = req.body.displayName || user.displayName;
- user.email = req.body.email || user.email;
- user.save(function(err) {
- res.status(200).end();
- });
- });
- });
- /*
- |--------------------------------------------------------------------------
- | Log in with Email
- |--------------------------------------------------------------------------
- */
- app.post('/auth/login', function(req, res) {
- User.findOne({ email: req.body.email }, '+password', function(err, user) {
- if (!user) {
- return res.status(401).send({ message: 'Invalid email and/or password' });
- }
- user.comparePassword(req.body.password, function(err, isMatch) {
- if (!isMatch) {
- return res.status(401).send({ message: 'Invalid email and/or password' });
- }
- res.send({ token: createJWT(user) });
- });
- });
- });
- /*
- |--------------------------------------------------------------------------
- | Create Email and Password Account
- |--------------------------------------------------------------------------
- */
- app.post('/auth/signup', function(req, res) {
- User.findOne({ email: req.body.email }, function(err, existingUser) {
- if (existingUser) {
- return res.status(409).send({ message: 'Email is already taken' });
- }
- var user = new User({
- displayName: req.body.displayName,
- email: req.body.email,
- password: req.body.password
- });
- user.save(function(err, result) {
- if (err) {
- res.status(500).send({ message: err.message });
- }
- res.send({ token: createJWT(result) });
- });
- });
- });
- /*
- |--------------------------------------------------------------------------
- | Login with Google
- |--------------------------------------------------------------------------
- */
- app.post('/auth/google', function(req, res) {
- var accessTokenUrl = 'https://accounts.google.com/o/oauth2/token';
- var peopleApiUrl = 'https://www.googleapis.com/plus/v1/people/me/openIdConnect';
- var params = {
- code: req.body.code,
- client_id: req.body.clientId,
- client_secret: config.GOOGLE_SECRET,
- redirect_uri: req.body.redirectUri,
- grant_type: 'authorization_code'
- };
- // Step 1. Exchange authorization code for access token.
- request.post(accessTokenUrl, { json: true, form: params }, function(err, response, token) {
- var accessToken = token.access_token;
- var headers = { Authorization: 'Bearer ' + accessToken };
- // Step 2. Retrieve profile information about the current user.
- request.get({ url: peopleApiUrl, headers: headers, json: true }, function(err, response, profile) {
- if (profile.error) {
- return res.status(500).send({message: profile.error.message});
- }
- // Step 3a. Link user accounts.
- if (req.header('Authorization')) {
- User.findOne({ google: profile.sub }, function(err, existingUser) {
- if (existingUser) {
- return res.status(409).send({ message: 'There is already a Google account that belongs to you' });
- }
- var token = req.header('Authorization').split(' ')[1];
- var payload = jwt.decode(token, config.TOKEN_SECRET);
- User.findById(payload.sub, function(err, user) {
- if (!user) {
- return res.status(400).send({ message: 'User not found' });
- }
- user.google = profile.sub;
- user.picture = user.picture || profile.picture.replace('sz=50', 'sz=200');
- user.displayName = user.displayName || profile.name;
- user.save(function() {
- var token = createJWT(user);
- res.send({ token: token });
- });
- });
- });
- } else {
- // Step 3b. Create a new user account or return an existing one.
- User.findOne({ google: profile.sub }, function(err, existingUser) {
- if (existingUser) {
- return res.send({ token: createJWT(existingUser) });
- }
- var user = new User();
- user.google = profile.sub;
- user.picture = profile.picture.replace('sz=50', 'sz=200');
- user.displayName = profile.name;
- user.save(function(err) {
- var token = createJWT(user);
- res.send({ token: token });
- });
- });
- }
- });
- });
- });
- /*
- |--------------------------------------------------------------------------
- | Login with GitHub
- |--------------------------------------------------------------------------
- */
- app.post('/auth/github', function(req, res) {
- var accessTokenUrl = 'https://github.com/login/oauth/access_token';
- var userApiUrl = 'https://api.github.com/user';
- var params = {
- code: req.body.code,
- client_id: req.body.clientId,
- client_secret: config.GITHUB_SECRET,
- redirect_uri: req.body.redirectUri
- };
- // Step 1. Exchange authorization code for access token.
- request.get({ url: accessTokenUrl, qs: params }, function(err, response, accessToken) {
- accessToken = qs.parse(accessToken);
- var headers = { 'User-Agent': 'Satellizer' };
- // Step 2. Retrieve profile information about the current user.
- request.get({ url: userApiUrl, qs: accessToken, headers: headers, json: true }, function(err, response, profile) {
- // Step 3a. Link user accounts.
- if (req.header('Authorization')) {
- User.findOne({ github: profile.id }, function(err, existingUser) {
- if (existingUser) {
- return res.status(409).send({ message: 'There is already a GitHub account that belongs to you' });
- }
- var token = req.header('Authorization').split(' ')[1];
- var payload = jwt.decode(token, config.TOKEN_SECRET);
- User.findById(payload.sub, function(err, user) {
- if (!user) {
- return res.status(400).send({ message: 'User not found' });
- }
- user.github = profile.id;
- user.picture = user.picture || profile.avatar_url;
- user.displayName = user.displayName || profile.name;
- user.save(function() {
- var token = createJWT(user);
- res.send({ token: token });
- });
- });
- });
- } else {
- // Step 3b. Create a new user account or return an existing one.
- User.findOne({ github: profile.id }, function(err, existingUser) {
- if (existingUser) {
- var token = createJWT(existingUser);
- return res.send({ token: token });
- }
- var user = new User();
- user.github = profile.id;
- user.picture = profile.avatar_url;
- user.displayName = profile.name;
- user.save(function() {
- var token = createJWT(user);
- res.send({ token: token });
- });
- });
- }
- });
- });
- });
- /*
- |--------------------------------------------------------------------------
- | Login with Instagram
- |--------------------------------------------------------------------------
- */
- app.post('/auth/instagram', function(req, res) {
- var accessTokenUrl = 'https://api.instagram.com/oauth/access_token';
- var params = {
- client_id: req.body.clientId,
- redirect_uri: req.body.redirectUri,
- client_secret: config.INSTAGRAM_SECRET,
- code: req.body.code,
- grant_type: 'authorization_code'
- };
- // Step 1. Exchange authorization code for access token.
- request.post({ url: accessTokenUrl, form: params, json: true }, function(error, response, body) {
- // Step 2a. Link user accounts.
- if (req.header('Authorization')) {
- User.findOne({ instagram: body.user.id }, function(err, existingUser) {
- if (existingUser) {
- return res.status(409).send({ message: 'There is already an Instagram account that belongs to you' });
- }
- var token = req.header('Authorization').split(' ')[1];
- var payload = jwt.decode(token, config.TOKEN_SECRET);
- User.findById(payload.sub, function(err, user) {
- if (!user) {
- return res.status(400).send({ message: 'User not found' });
- }
- user.instagram = body.user.id;
- user.picture = user.picture || body.user.profile_picture;
- user.displayName = user.displayName || body.user.username;
- user.save(function() {
- var token = createJWT(user);
- res.send({ token: token });
- });
- });
- });
- } else {
- // Step 2b. Create a new user account or return an existing one.
- User.findOne({ instagram: body.user.id }, function(err, existingUser) {
- if (existingUser) {
- return res.send({ token: createJWT(existingUser) });
- }
- var user = new User({
- instagram: body.user.id,
- picture: body.user.profile_picture,
- displayName: body.user.username
- });
- user.save(function() {
- var token = createJWT(user);
- res.send({ token: token, user: user });
- });
- });
- }
- });
- });
- /*
- |--------------------------------------------------------------------------
- | Login with LinkedIn
- |--------------------------------------------------------------------------
- */
- app.post('/auth/linkedin', function(req, res) {
- var accessTokenUrl = 'https://www.linkedin.com/uas/oauth2/accessToken';
- var peopleApiUrl = 'https://api.linkedin.com/v1/people/~:(id,first-name,last-name,email-address,picture-url)';
- var params = {
- code: req.body.code,
- client_id: req.body.clientId,
- client_secret: config.LINKEDIN_SECRET,
- redirect_uri: req.body.redirectUri,
- grant_type: 'authorization_code'
- };
- // Step 1. Exchange authorization code for access token.
- request.post(accessTokenUrl, { form: params, json: true }, function(err, response, body) {
- if (response.statusCode !== 200) {
- return res.status(response.statusCode).send({ message: body.error_description });
- }
- var params = {
- oauth2_access_token: body.access_token,
- format: 'json'
- };
- // Step 2. Retrieve profile information about the current user.
- request.get({ url: peopleApiUrl, qs: params, json: true }, function(err, response, profile) {
- // Step 3a. Link user accounts.
- if (req.header('Authorization')) {
- User.findOne({ linkedin: profile.id }, function(err, existingUser) {
- if (existingUser) {
- return res.status(409).send({ message: 'There is already a LinkedIn account that belongs to you' });
- }
- var token = req.header('Authorization').split(' ')[1];
- var payload = jwt.decode(token, config.TOKEN_SECRET);
- User.findById(payload.sub, function(err, user) {
- if (!user) {
- return res.status(400).send({ message: 'User not found' });
- }
- user.linkedin = profile.id;
- user.picture = user.picture || profile.pictureUrl;
- user.displayName = user.displayName || profile.firstName + ' ' + profile.lastName;
- user.save(function() {
- var token = createJWT(user);
- res.send({ token: token });
- });
- });
- });
- } else {
- // Step 3b. Create a new user account or return an existing one.
- User.findOne({ linkedin: profile.id }, function(err, existingUser) {
- if (existingUser) {
- return res.send({ token: createJWT(existingUser) });
- }
- var user = new User();
- user.linkedin = profile.id;
- user.picture = profile.pictureUrl;
- user.displayName = profile.firstName + ' ' + profile.lastName;
- user.save(function() {
- var token = createJWT(user);
- res.send({ token: token });
- });
- });
- }
- });
- });
- });
- /*
- |--------------------------------------------------------------------------
- | Login with Windows Live
- |--------------------------------------------------------------------------
- */
- app.post('/auth/live', function(req, res) {
- async.waterfall([
- // Step 1. Exchange authorization code for access token.
- function(done) {
- var accessTokenUrl = 'https://login.live.com/oauth20_token.srf';
- var params = {
- code: req.body.code,
- client_id: req.body.clientId,
- client_secret: config.WINDOWS_LIVE_SECRET,
- redirect_uri: req.body.redirectUri,
- grant_type: 'authorization_code'
- };
- request.post(accessTokenUrl, { form: params, json: true }, function(err, response, accessToken) {
- done(null, accessToken);
- });
- },
- // Step 2. Retrieve profile information about the current user.
- function(accessToken, done) {
- var profileUrl = 'https://apis.live.net/v5.0/me?access_token=' + accessToken.access_token;
- request.get({ url: profileUrl, json: true }, function(err, response, profile) {
- done(err, profile);
- });
- },
- function(profile) {
- // Step 3a. Link user accounts.
- if (req.header('Authorization')) {
- User.findOne({ live: profile.id }, function(err, user) {
- if (user) {
- return res.status(409).send({ message: 'There is already a Windows Live account that belongs to you' });
- }
- var token = req.header('Authorization').split(' ')[1];
- var payload = jwt.decode(token, config.TOKEN_SECRET);
- User.findById(payload.sub, function(err, existingUser) {
- if (!existingUser) {
- return res.status(400).send({ message: 'User not found' });
- }
- existingUser.live = profile.id;
- existingUser.displayName = existingUser.displayName || profile.name;
- existingUser.save(function() {
- var token = createJWT(existingUser);
- res.send({ token: token });
- });
- });
- });
- } else {
- // Step 3b. Create a new user or return an existing account.
- User.findOne({ live: profile.id }, function(err, user) {
- if (user) {
- return res.send({ token: createJWT(user) });
- }
- var newUser = new User();
- newUser.live = profile.id;
- newUser.displayName = profile.name;
- newUser.save(function() {
- var token = createJWT(newUser);
- res.send({ token: token });
- });
- });
- }
- }
- ]);
- });
- /*
- |--------------------------------------------------------------------------
- | Login with Facebook
- |--------------------------------------------------------------------------
- */
- app.post('/auth/facebook', function(req, res) {
- var fields = ['id', 'email', 'first_name', 'last_name', 'link', 'name'];
- var accessTokenUrl = 'https://graph.facebook.com/v2.5/oauth/access_token';
- var graphApiUrl = 'https://graph.facebook.com/v2.5/me?fields=' + fields.join(',');
- var params = {
- code: req.body.code,
- client_id: req.body.clientId,
- client_secret: config.FACEBOOK_SECRET,
- redirect_uri: req.body.redirectUri
- };
- // Step 1. Exchange authorization code for access token.
- request.get({ url: accessTokenUrl, qs: params, json: true }, function(err, response, accessToken) {
- if (response.statusCode !== 200) {
- return res.status(500).send({ message: accessToken.error.message });
- }
- // Step 2. Retrieve profile information about the current user.
- request.get({ url: graphApiUrl, qs: accessToken, json: true }, function(err, response, profile) {
- if (response.statusCode !== 200) {
- return res.status(500).send({ message: profile.error.message });
- }
- if (req.header('Authorization')) {
- User.findOne({ facebook: profile.id }, function(err, existingUser) {
- if (existingUser) {
- return res.status(409).send({ message: 'There is already a Facebook account that belongs to you' });
- }
- var token = req.header('Authorization').split(' ')[1];
- var payload = jwt.decode(token, config.TOKEN_SECRET);
- User.findById(payload.sub, function(err, user) {
- if (!user) {
- return res.status(400).send({ message: 'User not found' });
- }
- user.facebook = profile.id;
- user.picture = user.picture || 'https://graph.facebook.com/v2.3/' + profile.id + '/picture?type=large';
- user.displayName = user.displayName || profile.name;
- user.save(function() {
- var token = createJWT(user);
- res.send({ token: token });
- });
- });
- });
- } else {
- // Step 3. Create a new user account or return an existing one.
- User.findOne({ facebook: profile.id }, function(err, existingUser) {
- if (existingUser) {
- var token = createJWT(existingUser);
- return res.send({ token: token });
- }
- var user = new User();
- user.facebook = profile.id;
- user.picture = 'https://graph.facebook.com/' + profile.id + '/picture?type=large';
- user.displayName = profile.name;
- user.save(function() {
- var token = createJWT(user);
- res.send({ token: token });
- });
- });
- }
- });
- });
- });
- /*
- |--------------------------------------------------------------------------
- | Login with Yahoo
- |--------------------------------------------------------------------------
- */
- app.post('/auth/yahoo', function(req, res) {
- var accessTokenUrl = 'https://api.login.yahoo.com/oauth2/get_token';
- var clientId = req.body.clientId;
- var clientSecret = config.YAHOO_SECRET;
- var formData = {
- code: req.body.code,
- redirect_uri: req.body.redirectUri,
- grant_type: 'authorization_code'
- };
- var headers = { Authorization: 'Basic ' + new Buffer(clientId + ':' + clientSecret).toString('base64') };
- // Step 1. Exchange authorization code for access token.
- request.post({ url: accessTokenUrl, form: formData, headers: headers, json: true }, function(err, response, body) {
- var socialApiUrl = 'https://social.yahooapis.com/v1/user/' + body.xoauth_yahoo_guid + '/profile?format=json';
- var headers = { Authorization: 'Bearer ' + body.access_token };
- // Step 2. Retrieve profile information about the current user.
- request.get({ url: socialApiUrl, headers: headers, json: true }, function(err, response, body) {
- // Step 3a. Link user accounts.
- if (req.header('Authorization')) {
- User.findOne({ yahoo: body.profile.guid }, function(err, existingUser) {
- if (existingUser) {
- return res.status(409).send({ message: 'There is already a Yahoo account that belongs to you' });
- }
- var token = req.header('Authorization').split(' ')[1];
- var payload = jwt.decode(token, config.TOKEN_SECRET);
- User.findById(payload.sub, function(err, user) {
- if (!user) {
- return res.status(400).send({ message: 'User not found' });
- }
- user.yahoo = body.profile.guid;
- user.displayName = user.displayName || body.profile.nickname;
- user.save(function() {
- var token = createJWT(user);
- res.send({ token: token });
- });
- });
- });
- } else {
- // Step 3b. Create a new user account or return an existing one.
- User.findOne({ yahoo: body.profile.guid }, function(err, existingUser) {
- if (existingUser) {
- return res.send({ token: createJWT(existingUser) });
- }
- var user = new User();
- user.yahoo = body.profile.guid;
- user.displayName = body.profile.nickname;
- user.save(function() {
- var token = createJWT(user);
- res.send({ token: token });
- });
- });
- }
- });
- });
- });
- /*
- |--------------------------------------------------------------------------
- | Login with Twitter
- |--------------------------------------------------------------------------
- */
- app.post('/auth/twitter', function(req, res) {
- var requestTokenUrl = 'https://api.twitter.com/oauth/request_token';
- var accessTokenUrl = 'https://api.twitter.com/oauth/access_token';
- var profileUrl = 'https://api.twitter.com/1.1/users/show.json?screen_name=';
- // Part 1 of 2: Initial request from Satellizer.
- if (!req.body.oauth_token || !req.body.oauth_verifier) {
- var requestTokenOauth = {
- consumer_key: config.TWITTER_KEY,
- consumer_secret: config.TWITTER_SECRET,
- callback: req.body.redirectUri
- };
- // Step 1. Obtain request token for the authorization popup.
- request.post({ url: requestTokenUrl, oauth: requestTokenOauth }, function(err, response, body) {
- var oauthToken = qs.parse(body);
- // Step 2. Send OAuth token back to open the authorization screen.
- res.send(oauthToken);
- });
- } else {
- // Part 2 of 2: Second request after Authorize app is clicked.
- var accessTokenOauth = {
- consumer_key: config.TWITTER_KEY,
- consumer_secret: config.TWITTER_SECRET,
- token: req.body.oauth_token,
- verifier: req.body.oauth_verifier
- };
- // Step 3. Exchange oauth token and oauth verifier for access token.
- request.post({ url: accessTokenUrl, oauth: accessTokenOauth }, function(err, response, accessToken) {
- accessToken = qs.parse(accessToken);
- var profileOauth = {
- consumer_key: config.TWITTER_KEY,
- consumer_secret: config.TWITTER_SECRET,
- oauth_token: accessToken.oauth_token
- };
- // Step 4. Retrieve profile information about the current user.
- request.get({
- url: profileUrl + accessToken.screen_name,
- oauth: profileOauth,
- json: true
- }, function(err, response, profile) {
- // Step 5a. Link user accounts.
- if (req.header('Authorization')) {
- User.findOne({ twitter: profile.id }, function(err, existingUser) {
- if (existingUser) {
- return res.status(409).send({ message: 'There is already a Twitter account that belongs to you' });
- }
- var token = req.header('Authorization').split(' ')[1];
- var payload = jwt.decode(token, config.TOKEN_SECRET);
- User.findById(payload.sub, function(err, user) {
- if (!user) {
- return res.status(400).send({ message: 'User not found' });
- }
- user.twitter = profile.id;
- user.displayName = user.displayName || profile.name;
- user.picture = user.picture || profile.profile_image_url.replace('_normal', '');
- user.save(function(err) {
- res.send({ token: createJWT(user) });
- });
- });
- });
- } else {
- // Step 5b. Create a new user account or return an existing one.
- User.findOne({ twitter: profile.id }, function(err, existingUser) {
- if (existingUser) {
- return res.send({ token: createJWT(existingUser) });
- }
- var user = new User();
- user.twitter = profile.id;
- user.displayName = profile.name;
- user.picture = profile.profile_image_url.replace('_normal', '');
- user.save(function() {
- res.send({ token: createJWT(user) });
- });
- });
- }
- });
- });
- }
- });
- /*
- |--------------------------------------------------------------------------
- | Login with Foursquare
- |--------------------------------------------------------------------------
- */
- app.post('/auth/foursquare', function(req, res) {
- var accessTokenUrl = 'https://foursquare.com/oauth2/access_token';
- var profileUrl = 'https://api.foursquare.com/v2/users/self';
- var formData = {
- code: req.body.code,
- client_id: req.body.clientId,
- client_secret: config.FOURSQUARE_SECRET,
- redirect_uri: req.body.redirectUri,
- grant_type: 'authorization_code'
- };
- // Step 1. Exchange authorization code for access token.
- request.post({ url: accessTokenUrl, form: formData, json: true }, function(err, response, body) {
- var params = {
- v: '20140806',
- oauth_token: body.access_token
- };
- // Step 2. Retrieve information about the current user.
- request.get({ url: profileUrl, qs: params, json: true }, function(err, response, profile) {
- profile = profile.response.user;
- // Step 3a. Link user accounts.
- if (req.header('Authorization')) {
- User.findOne({ foursquare: profile.id }, function(err, existingUser) {
- if (existingUser) {
- return res.status(409).send({ message: 'There is already a Foursquare account that belongs to you' });
- }
- var token = req.header('Authorization').split(' ')[1];
- var payload = jwt.decode(token, config.TOKEN_SECRET);
- User.findById(payload.sub, function(err, user) {
- if (!user) {
- return res.status(400).send({ message: 'User not found' });
- }
- user.foursquare = profile.id;
- user.picture = user.picture || profile.photo.prefix + '300x300' + profile.photo.suffix;
- user.displayName = user.displayName || profile.firstName + ' ' + profile.lastName;
- user.save(function() {
- var token = createJWT(user);
- res.send({ token: token });
- });
- });
- });
- } else {
- // Step 3b. Create a new user account or return an existing one.
- User.findOne({ foursquare: profile.id }, function(err, existingUser) {
- if (existingUser) {
- var token = createJWT(existingUser);
- return res.send({ token: token });
- }
- var user = new User();
- user.foursquare = profile.id;
- user.picture = profile.photo.prefix + '300x300' + profile.photo.suffix;
- user.displayName = profile.firstName + ' ' + profile.lastName;
- user.save(function() {
- var token = createJWT(user);
- res.send({ token: token });
- });
- });
- }
- });
- });
- });
- /*
- |--------------------------------------------------------------------------
- | Login with Twitch
- |--------------------------------------------------------------------------
- */
- app.post('/auth/twitch', function(req, res) {
- var accessTokenUrl = 'https://api.twitch.tv/kraken/oauth2/token';
- var profileUrl = 'https://api.twitch.tv/kraken/user';
- var formData = {
- code: req.body.code,
- client_id: req.body.clientId,
- client_secret: config.TWITCH_SECRET,
- redirect_uri: req.body.redirectUri,
- grant_type: 'authorization_code'
- };
- // Step 1. Exchange authorization code for access token.
- request.post({ url: accessTokenUrl, form: formData, json: true }, function(err, response, accessToken) {
- var params = {
- oauth_token: accessToken.access_token
- };
- // Step 2. Retrieve information about the current user.
- request.get({ url: profileUrl, qs: params, json: true }, function(err, response, profile) {
- // Step 3a. Link user accounts.
- if (req.header('Authorization')) {
- User.findOne({ twitch: profile._id }, function(err, existingUser) {
- if (existingUser) {
- return res.status(409).send({ message: 'There is already a Twitch account that belongs to you' });
- }
- var token = req.header('Authorization').split(' ')[1];
- var payload = jwt.decode(token, config.TOKEN_SECRET);
- User.findById(payload.sub, function(err, user) {
- if (!user) {
- return res.status(400).send({ message: 'User not found' });
- }
- user.twitch = profile._id;
- user.picture = user.picture || profile.logo;
- user.displayName = user.name || profile.name;
- user.email = user.email || profile.email;
- user.save(function() {
- var token = createJWT(user);
- res.send({ token: token });
- });
- });
- });
- } else {
- // Step 3b. Create a new user account or return an existing one.
- User.findOne({ twitch: profile._id }, function(err, existingUser) {
- if (existingUser) {
- var token = createJWT(existingUser);
- return res.send({ token: token });
- }
- var user = new User();
- user.twitch = profile._id;
- user.picture = profile.logo;
- user.displayName = profile.name;
- user.email = profile.email;
- user.save(function() {
- var token = createJWT(user);
- res.send({ token: token });
- });
- });
- }
- });
- });
- });
- /*
- |--------------------------------------------------------------------------
- | Login with Bitbucket
- |--------------------------------------------------------------------------
- */
- app.post('/auth/bitbucket', function(req, res) {
- var accessTokenUrl = 'https://bitbucket.org/site/oauth2/access_token';
- var userApiUrl = 'https://bitbucket.org/api/2.0/user';
- var emailApiUrl = 'https://bitbucket.org/api/2.0/user/emails';
- var headers = {
- Authorization: 'Basic ' + new Buffer(req.body.clientId + ':' + config.BITBUCKET_SECRET).toString('base64')
- };
- var formData = {
- code: req.body.code,
- redirect_uri: req.body.redirectUri,
- grant_type: 'authorization_code'
- };
- // Step 1. Exchange authorization code for access token.
- request.post({ url: accessTokenUrl, form: formData, headers: headers, json: true }, function(err, response, body) {
- if (body.error) {
- return res.status(400).send({ message: body.error_description });
- }
-
- var params = {
- access_token: body.access_token
- };
- // Step 2. Retrieve information about the current user.
- request.get({ url: userApiUrl, qs: params, json: true }, function(err, response, profile) {
- // Step 2.5. Retrieve current user's email.
- request.get({ url: emailApiUrl, qs: params, json: true }, function(err, response, emails) {
- var email = emails.values[0].email;
- // Step 3a. Link user accounts.
- if (req.header('Authorization')) {
- User.findOne({ bitbucket: profile.uuid }, function(err, existingUser) {
- if (existingUser) {
- return res.status(409).send({ message: 'There is already a Bitbucket account that belongs to you' });
- }
- var token = req.header('Authorization').split(' ')[1];
- var payload = jwt.decode(token, config.TOKEN_SECRET);
- User.findById(payload.sub, function(err, user) {
- if (!user) {
- return res.status(400).send({ message: 'User not found' });
- }
- user.bitbucket = profile.uuid;
- user.email = user.email || email;
- user.picture = user.picture || profile.links.avatar.href;
- user.displayName = user.displayName || profile.display_name;
- user.save(function() {
- var token = createJWT(user);
- res.send({ token: token });
- });
- });
- });
- } else {
- // Step 3b. Create a new user account or return an existing one.
- User.findOne({ bitbucket: profile.id }, function(err, existingUser) {
- if (existingUser) {
- var token = createJWT(existingUser);
- return res.send({ token: token });
- }
- var user = new User();
- user.bitbucket = profile.uuid;
- user.email = email;
- user.picture = profile.links.avatar.href;
- user.displayName = profile.display_name;
- user.save(function() {
- var token = createJWT(user);
- res.send({ token: token });
- });
- });
- }
- });
- });
- });
- });
- /*
- |--------------------------------------------------------------------------
- | Unlink Provider
- |--------------------------------------------------------------------------
- */
- app.post('/auth/unlink', ensureAuthenticated, function(req, res) {
- var provider = req.body.provider;
- var providers = ['facebook', 'foursquare', 'google', 'github', 'instagram',
- 'linkedin', 'live', 'twitter', 'twitch', 'yahoo'];
- if (providers.indexOf(provider) === -1) {
- return res.status(400).send({ message: 'Unknown OAuth Provider' });
- }
- User.findById(req.user, function(err, user) {
- if (!user) {
- return res.status(400).send({ message: 'User Not Found' });
- }
- user[provider] = undefined;
- user.save(function() {
- res.status(200).end();
- });
- });
- });
- /*
- |--------------------------------------------------------------------------
- | Start the Server
- |--------------------------------------------------------------------------
- */
- app.listen(app.get('port'), app.get('host'), function() {
- console.log('Express server listening on port ' + app.get('port'));
- });
|