Skip to content

Commit

Permalink
(bg-social-login): fix issue with the social login
Browse files Browse the repository at this point in the history
users should be able to receive a jwt token when they login/register with their social account

implement twitter login to generate jwt token

[Finishes #164658918]
  • Loading branch information
Dubby20 committed Mar 18, 2019
1 parent a1f7459 commit 4057cdc
Show file tree
Hide file tree
Showing 7 changed files with 311 additions and 83 deletions.
154 changes: 87 additions & 67 deletions auth/passport.js
Original file line number Diff line number Diff line change
@@ -1,45 +1,45 @@
import passport from 'passport';
import { OAuth2Strategy as GoogleStrategy } from 'passport-google-oauth';
import { Strategy as FacebookStrategy } from 'passport-facebook';
import { Strategy as TwitterStrategy } from 'passport-twitter';
import { User } from '../models';

passport.use(new GoogleStrategy(
{
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: `${process.env.HOST_URL}/api/v1/auth/google/callback`,
},
/**
/**
* callback function for google strategy
* @param {object} accessToken authorization token
* @param {object} refreshToken authorization token
* @param {object} profile a user profile
* @param {function} done end of function
* @returns {function} callback
*/
async (accessToken, refreshToken, profile, done) => {
const email = profile.emails[0].value;
/**
* @description - finds an existing user or create a new user
* @param {object} user a user
* @param {function} done end of function
* @returns {object} createOrFindUser
*/
const {
displayName,
name: { givenName }
} = profile;
const user = await User.findOrCreate({
where: { email },
defaults: {
name: displayName,
username: givenName,
email
}
});
return done(null, user[0].dataValues);
}
));
export const googleSocial = async (accessToken, refreshToken, profile, done) => {
const email = profile.emails[0].value;
/**
* @description - finds an existing user or create a new user
* @param {object} user a user
* @param {function} done end of function
* @returns {object} createOrFindUser
*/
const {
displayName,
name: { givenName }
} = profile;
const user = await User.findOrCreate({
where: { email },
defaults: {
name: displayName,
username: givenName,
email
}
});
return done(null, user[0].dataValues);
};
passport.use(new GoogleStrategy({
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: `${process.env.HOST_URL}/api/v1/auth/google/callback`,
}, googleSocial));


/**
* callback function for facebook strategy
Expand All @@ -49,55 +49,75 @@ passport.use(new GoogleStrategy(
* @param {function} done end of function
* @returns {function} callback
*/
export const facebookSocial = async (accessToken, refreshToken, profile, done) => {
const email = profile.emails[0].value;
const splitName = profile.displayName.split(' ');
const username = splitName[0];
/**
* @description - finds an existing user or create a new user
* @param {object} user a user
* @param {function} done end of function
* @returns {object} createOrFindUser
*/
const { displayName } = profile;
const user = await User.findOrCreate({
where: { email },
defaults: {
name: displayName,
username,
email
}
});
return done(null, user[0]);
};

passport.use(new FacebookStrategy(
{
clientID: process.env.FACEBOOK_CLIENT_ID,
clientSecret: process.env.FACEBOOK_CLIENT_SECRET,
callbackURL: `${process.env.HOST_URL}/api/v1/auth/facebook/callback`,
profileFields: ['id', 'displayName', 'email']
},
async (accessToken, refreshToken, profile, done) => {
const email = profile.emails[0].value;
const splitName = profile.displayName.split(' ');
const username = splitName[0];
/**
}, facebookSocial
));


/**
* callback function for twitter strategy
* @param {object} token authorization token
* @param {object} tokenSecret authorization token
* @param {object} profile a user profile
* @param {function} done end of function
* @returns {function} callback
*/
export const twitterSocial = async (token, tokenSecret, profile, done) => {
const email = profile.emails[0].value;
/**
* @description - finds an existing user or create a new user
* @param {object} user a user
* @param {function} done end of function
* @returns {object} createOrFindUser
*/
const { displayName } = profile;
const user = await User.findOrCreate({
where: { email },
defaults: {
name: displayName,
username,
email
}
});
return done(null, user[0]);
}
));
const { displayName, username } = profile;
const user = await User.findOrCreate({
where: { email },
defaults: {
name: displayName,
username,
email
}
});
return done(null, user[0]);
};

/**
* @description - set the user id
* @param {object} user a user
* @param {function} done end of function
* @returns {object} user id
*/
passport.serializeUser((user, done) => {
done(null, user.id);
});

/**
* @description - finds the user by id
* @param {object} user a user
* @param {function} done end of function
* @returns {object} user profile
*/
passport.deserializeUser(async (id, done) => {
const user = await User.findByPk(id);
return done(null, user);
});
passport.use(new TwitterStrategy(
{
consumerKey: process.env.TWITTER_CONSUMER_KEY,
consumerSecret: process.env.TWITTER_CONSUMER_SECRET,
callbackURL: `${process.env.HOST_URL}/api/v1/auth/twitter/callback`,
includeEmail: true
}, twitterSocial
));


export default passport;
26 changes: 26 additions & 0 deletions controllers/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,4 +222,30 @@ export default class UserController {
message: 'Password changed successfully.'
});
}

/**
* Returns a token when a user logs in via social account
* @static
* @param {req} req - Request object
* @param {res} res - Response object
* @returns {object} - User object
*/
static async socialAuth(req, res) {
const {
user
} = req;
try {
const token = generateToken(user.id);
return res.status(200).json({
success: true,
message: `Welcome ${user.username}`,
token
});
} catch (err) {
return res.status(500).json({
sucess: false,
errors: [err.message]
});
}
}
}
24 changes: 23 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import express from 'express';
import bodyParser from 'body-parser';
import morgan from 'morgan';
import session from 'express-session';
import cors from 'cors';
import passport from 'passport';
import errorhandler from 'errorhandler';
import dotenv from 'dotenv';
import swaggerUI from 'swagger-ui-express';
import routes from './routes/index';
import doc from './doc.json';
import { User } from './models';


// read .env config
dotenv.config();
Expand All @@ -22,8 +25,27 @@ app.use(cors());
app.use(morgan('combined'));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

app.use(session({
secret: process.env.SECRET,
key: 'vidar',
resave: true,
saveUninitialized: true,
cookie: {
maxAge: 60000,
expires: false
}
}));
app.use(passport.initialize());
app.use(passport.session());

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

passport.deserializeUser(async (id, done) => {
const user = await User.findByPk(id);
return done(null, user);
});

// configure router
app.use('/api', routes);
Expand Down
Loading

0 comments on commit 4057cdc

Please sign in to comment.