Skip to content

Commit

Permalink
Merge e5976b1 into c72ba96
Browse files Browse the repository at this point in the history
  • Loading branch information
jnkindi committed Apr 9, 2019
2 parents c72ba96 + e5976b1 commit fd5a439
Show file tree
Hide file tree
Showing 18 changed files with 235 additions and 51 deletions.
8 changes: 8 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,12 @@ FacebookCallback_URL =
FACEBOOK_APP_ID =
FACEBOOK_APP_SECRET =

TWITTER_CONSUMER_KEY=
TWITTER_CONSUMER_SECRET=
TWITTER_CALLBACK=

GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
GITHUB_CALLBACK=

SECRETKEY =
7 changes: 6 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
sudo: false
language: node_js
node_js:
- "stable"
- 'stable'
install:
- npm i
script:
- npm run migrate
- npm run test
after_success:
- npm run coverage
notifications:
email: false
services:
- postgresql
before_script:
- psql -c 'create database travis_ci_test;' -U postgres
3 changes: 0 additions & 3 deletions config/index.js

This file was deleted.

27 changes: 0 additions & 27 deletions config/passport.js

This file was deleted.

1 change: 1 addition & 0 deletions controllers/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class User {
email: req.user.email,
firstname: req.user.firstname,
lastname: req.user.lastname,
bio: req.user.bio,
image: req.user.image,
provider: req.user.provider,
provideruserid: req.user.provideruserid
Expand Down
10 changes: 10 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,29 @@
import express from 'express';
import bodyParser from 'body-parser';
import passport from 'passport';
import session from 'express-session';
import swaggerUi from 'swagger-ui-express';
import YAML from 'yamljs';
import dotenv from 'dotenv';
import user from './routes/user';
import Strategy from './middlewares/auth';

dotenv.config();

const swaggerDocument = YAML.load('./swagger.yaml');

const app = express();

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

app.use(session({
secret: process.env.SECRETKEY,
resave: false,
saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());
const strategy = new Strategy();
app.use('/api/v1/login', user);
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument));
Expand Down
6 changes: 5 additions & 1 deletion middlewares/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import passport from 'passport';
import serializePassportUser from './serialize';
import facebookStrategy from './passportStrategy/facebook';
import GoogleStrategy from './passportStrategy/google';
import TwitterStrategy from './passportStrategy/twitter';
import GithubStrategy from './passportStrategy/github';
import models from '../models/index';

const { user } = models;
Expand All @@ -13,13 +15,15 @@ dotenv.config();
*/
class Strategy {
/**
* @author frank harerimana
* @author frank harerimana with Jacques Nyilinkindi
* @param {*} passport
* @return { O } strategy
*/
constructor() {
this.facebookStrategy = passport.use(facebookStrategy);
this.GoogleStrategy = passport.use(GoogleStrategy);
this.TwitterStrategy = passport.use(TwitterStrategy);
this.GithubStrategy = passport.use(GithubStrategy);
this.serializePassportUser = serializePassportUser(passport, user);
}
}
Expand Down
67 changes: 64 additions & 3 deletions middlewares/callbackHandler.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-disable no-underscore-dangle */
import usernameGenerator from './uniquestring';

const usernamestring = new usernameGenerator();
/**
* @author frank harerimana
* @param {*} accessToken
Expand All @@ -13,11 +14,10 @@ const GetSocial = async (accessToken, refreshToken, profile, done) => {
/**
* get unique formatted username
*/
const usernamestring = new usernameGenerator(profile.displayName);

const SocialUser = {
email: profile._json.email,
username: usernamestring.getUsername(),
username: usernamestring.getUsername(profile.displayName),
firstname: profile.name.familyName,
lastname: profile.name.givenName,
image: profile.photos[0].value,
Expand All @@ -27,4 +27,65 @@ const GetSocial = async (accessToken, refreshToken, profile, done) => {

done(null, SocialUser);
};
export default GetSocial;

/**
* @author Jacques Nyilinkindi
* @param {*} token
* @param {*} tokenSecret
* @param {*} profile
* @param {*} done
* @returns { Object } user
*/
const GetSocialTwitter = async (token, tokenSecret, profile, done) => {
/**
* get unique formatted username
*/
const { _json } = profile;
// _json.profile_image_url.
const image = usernamestring.generateLargeTwitterProfile(_json.profile_image_url);
const names = usernamestring.removeSpecialCharacters(_json.name);

const SocialUser = {
username: usernamestring.getUsername(profile.username),
firstname: names,
image,
bio: _json.description,
provider: _json.provider,
provideruserid: _json.id.toString()
};
done(null, SocialUser);
};

/**
* @author Jacques Nyilinkindi
* @param {*} accessToken
* @param {*} refreshToken
* @param {*} profile
* @param {*} done
* @returns { Object } user
*/
const GetSocialGithub = async (accessToken, refreshToken, profile, done) => {
console.log(profile);
/**
* get unique formatted username
*/
const { _json } = profile;
// _json.profile_image_url.
const image = _json.avatar_url;
const names = usernamestring.removeSpecialCharacters(_json.name);

const SocialUser = {
username: usernamestring.getUsername(profile.username),
firstname: names,
image,
bio: _json.bio,
provider: profile.provider,
provideruserid: _json.id.toString()
};
done(null, SocialUser);
};
export {
GetSocial,
GetSocialTwitter,
GetSocialGithub
};
2 changes: 1 addition & 1 deletion middlewares/passportStrategy/facebook.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import FacebookStrategy from 'passport-facebook';
import GetSocial from '../callbackHandler';
import { GetSocial } from '../callbackHandler';
/**
* @author frank harerimana
* @returns Facebook strategy
Expand Down
17 changes: 17 additions & 0 deletions middlewares/passportStrategy/github.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import GithubStrategy from 'passport-github';
import { GetSocialGithub } from '../callbackHandler';
/**
* @author Jacques Nyilinkindi
* @returns Github strategy
*/
const Github = new GithubStrategy({
clientID: process.env.GITHUB_CLIENT_ID,
clientSecret: process.env.GITHUB_CLIENT_SECRET,
callbackURL: process.env.GITHUB_CALLBACK
},
async (accessToken, refreshToken, profile, done) => {
GetSocialGithub(
accessToken, refreshToken, profile, done
);
});
export default Github;
2 changes: 1 addition & 1 deletion middlewares/passportStrategy/google.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import GoogleStrategy from 'passport-google-oauth20';
import GetSocial from '../callbackHandler';
import { GetSocial } from '../callbackHandler';

/**
* @author frank harerimana
Expand Down
17 changes: 17 additions & 0 deletions middlewares/passportStrategy/twitter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import TwitterStrategy from 'passport-twitter';
import { GetSocialTwitter } from '../callbackHandler';
/**
* @author Jacques Nyilinkindi
* @returns Twitter strategy
*/
const Twitter = new TwitterStrategy({
consumerKey: process.env.TWITTER_CONSUMER_KEY,
consumerSecret: process.env.TWITTER_CONSUMER_SECRET,
callbackURL: process.env.TWITTER_CALLBACK,
},
async (token, tokenSecret, profile, done) => {
GetSocialTwitter(
token, tokenSecret, profile, done
);
});
export default Twitter;
2 changes: 1 addition & 1 deletion middlewares/serialize.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const serializePassportUser = (passport, user) => {
done(null, SocialUser.provideruserid);
});
passport.deserializeUser((provideruserid, done) => {
user.findByPk(provideruserid).then((SocialUser) => {
user.findAll({ where: { provideruserid } }).then((SocialUser) => {
done(null, SocialUser);
})
.catch(err => done(err, false));
Expand Down
31 changes: 25 additions & 6 deletions middlewares/uniquestring.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,42 @@
/* eslint-disable class-methods-use-this */
/**
* @author frank harerimana
* Generate unique username
*/
class Generate {
/**
* @param {*} strings
*/
constructor(strings) {
this.strings = strings;
* @author frank harerimana
*/
constructor() {
this.randomNumber = Math.floor(Math.random() * 10000);
this.randomString = Math.random().toString(36).slice(2);
}

/**
* @author frank harerimana
* @param { String } name
* @returns { String } username
*/
getUsername() {
return this.strings.replace(/\s/g, '-').toLowerCase() + this.randomNumber;
getUsername(name) {
return name.replace(/\s/g, '-').toLowerCase() + this.randomNumber;
}

/**
* @author Jacques Nyilinkindi
* @param { String } words
* @returns { String } string
*/
removeSpecialCharacters(words) {
return words.replace(/[^a-zA-Z ]/g, '').trim();
}

/**
* @author Jacques Nyilinkindi
* @param { String } image
* @returns { String } string
*/
generateLargeTwitterProfile(image) {
return image.replace('_normal', '');
}
}
export default Generate;
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
"description": "A Social platform for the creative at heart",
"main": "index.js",
"scripts": {
"test": "NODE_ENV=test nyc --reporter=html --reporter=text mocha --require @babel/polyfill --require @babel/register ./test/*.js --exit",
"test": "NODE_ENV=test npm run migrate && nyc --reporter=html --reporter=text mocha --require @babel/polyfill --require @babel/register ./test/*.js --exit",
"start": "babel-node ./index.js",
"migrate": "sequelize db:migrate:undo && sequelize db:migrate",
"dev": "nodemon --exec babel-node ./index.js ",
"coverage": "nyc report --reporter=text-lcov | coveralls",
"lint": "eslint ./",
Expand Down Expand Up @@ -34,8 +35,10 @@
"morgan": "^1.9.1",
"passport": "^0.4.0",
"passport-facebook": "^3.0.0",
"passport-github": "^1.1.0",
"passport-google-oauth20": "^2.0.0",
"passport-linkedin": "^1.0.0",
"passport-twitter": "^1.0.4",
"pg": "^7.9.0",
"request": "^2.87.0",
"sequelize": "^4.42.0",
Expand Down
10 changes: 8 additions & 2 deletions routes/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,16 @@ import user from '../controllers/user';

const route = express.Router();

route.get('/auth/google', passport.authenticate('google', { scope: ['email', 'profile'] }));
route.get('/auth/google', passport.authenticate('google', { session: false, scope: ['email', 'profile'] }));
route.get('/google/redirect', passport.authenticate('google', { failureRedirect: 'auth/google' }), user.socialLogin);
// passport.authenticate('google', user.googleLogin)
route.get('/auth/facebook', passport.authenticate('facebook', { scope: ['email'] }));
route.get('/auth/facebook/callback', passport.authenticate('facebook', { failureRedirect: '/auth/facebook' }), user.socialLogin);
route.get('/auth/facebook/callback', passport.authenticate('facebook', { session: false, failureRedirect: '/auth/facebook' }), user.socialLogin);
// passport.authenticate twitter
route.get('/auth/twitter', passport.authenticate('twitter'));
route.get('/auth/twitter/callback', passport.authenticate('twitter', { failureRedirect: '/auth/twitter' }), user.socialLogin);
// passport.authenticate github
route.get('/auth/github', passport.authenticate('github'));
route.get('/auth/github/callback', passport.authenticate('github', { failureRedirect: '/auth/github' }), user.socialLogin);

export default route;
Loading

0 comments on commit fd5a439

Please sign in to comment.