Last active
March 10, 2020 08:25
-
-
Save FBosler/ff8efceb2eac4dbef9e01c6ad651d43b to your computer and use it in GitHub Desktop.
backend_ii_iii
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const express = require("express"); | |
const router = express.Router(); | |
const passport = require("passport"); | |
const config = require("../config/config"); | |
const providerScopes = { | |
google: { scope: ["profile", "email"] }, | |
facebook: { scope: ["email"] }, | |
amazon: { scope: ["profile"] }, | |
github: {}, | |
twitter: {}, | |
spotify: { scope: ["user-read-email"] }, | |
twitch: { scope: ["user:read:email"] } | |
}; | |
router.post("/register_login", (req, res, next) => { | |
passport.authenticate("local", function(err, user, info) { | |
if (err) { | |
return res.status(400).json({ errors: err }); | |
} | |
if (!user) { | |
return res.status(400).json({ errors: "No user found" }); | |
} | |
req.logIn(user, function(err) { | |
if (err) { | |
return res.status(400).json({ errors: err }); | |
} | |
return res.status(200).json({ success: `logged in ${user.id}` }); | |
}); | |
})(req, res, next); | |
}); | |
// auth routers | |
router.get("/:provider", (req, res, next) => { | |
const provider = req.params.provider; | |
const scope = providerScopes[provider]; | |
const state = { state: JSON.stringify(req.query) }; | |
const options = { ...state, ...scope }; | |
if (provider === "twitter") { | |
req.session.state = JSON.stringify(req.query); | |
} | |
passport.authenticate(provider, options)(req, res, next); | |
}); | |
// callbacks | |
router.get( | |
"/:provider/callback", | |
(req, res, next) => { | |
passport.authenticate(req.params.provider)(req, res, next); | |
}, | |
(req, res) => { | |
const profile_uri = `${config.FRONT_END_URI}/profile`; | |
res.redirect(profile_uri); | |
} | |
); | |
module.exports = router; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let config = { | |
FRONT_END_URI: "http://localhost:3000" | |
}; | |
if (process.env.NODE_ENV === "production") { | |
// add production config as we move forward else { | |
} | |
// overwrite exports with env variables | |
config.MONGO_URI = process.env.MONGO_URI || config.MONGO_URI; | |
module.exports = config; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import AmazonIcon from "./icons/amazon.png"; | |
import FacebookIcon from "./icons/facebook.png"; | |
import GithubIcon from "./icons/github.png"; | |
import GoogleIcon from "./icons/google.png"; | |
import SpotifyIcon from "./icons/spotify.png"; | |
import TwitchIcon from "./icons/twitch.png"; | |
import TwitterIcon from "./icons/twitter.png"; | |
const providerData = [ | |
{ | |
img: AmazonIcon, | |
name: "amazon", | |
href: "auth/amazon", | |
alt: "amazon-icon", | |
color: "#F9AE31", | |
txt: "Login with Amazon" | |
}, | |
{ | |
img: FacebookIcon, | |
name: "facebook", | |
href: "auth/facebook", | |
alt: "facebook-icon", | |
color: "#3B5899", | |
txt: "Login with Facebook" | |
}, | |
{ | |
img: GithubIcon, | |
name: "github", | |
href: "auth/github", | |
alt: "github-icon", | |
color: "#333333", | |
txt: "Login with Github" | |
}, | |
{ | |
img: GoogleIcon, | |
name: "google", | |
href: "auth/google", | |
alt: "google-icon", | |
color: "#CB4024", | |
txt: "Login with Google" | |
}, | |
{ | |
img: SpotifyIcon, | |
name: "spotify", | |
href: "auth/spotify", | |
alt: "spotify-icon", | |
color: "#1EB954", | |
txt: "Login with Spotify" | |
}, | |
{ | |
img: TwitchIcon, | |
name: "twitch", | |
href: "auth/twitch", | |
alt: "twitch-icon", | |
color: "#5F3BAD", | |
txt: "Login with Twitch" | |
}, | |
{ | |
img: TwitterIcon, | |
name: "twitter", | |
href: "auth/twitter", | |
alt: "twitter-icon", | |
color: "#00acee", | |
txt: "Login with Twitter" | |
} | |
]; | |
export default providerData; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import providerData from "../../data/providerData"; | |
import { Col } from "react-bootstrap"; | |
import React from "react"; | |
import { ImageDiv, ColoredDiv, MarginedRow } from "./styles.js"; | |
const DelegatedAuthButton = ({ img, href, color, baseUrl }) => { | |
return ( | |
<Col xs={2} onClick={() => (window.location = `${baseUrl}/api/${href}`)} style={{ padding: "5px" }}> | |
<ColoredDiv color={color}> | |
<ImageDiv img={img} color={color} /> | |
</ColoredDiv> | |
</Col> | |
); | |
}; | |
const DelegatedAuthList = () => { | |
const baseUrl = window.location.hostname.includes("local") | |
? "http://localhost:5000" | |
: `${window.location.hostname}`; | |
return ( | |
<MarginedRow> | |
{providerData.map(provider => { | |
return <DelegatedAuthButton {...provider} baseUrl={baseUrl} key={provider.name} />; | |
})} | |
</MarginedRow> | |
); | |
}; | |
export default DelegatedAuthList; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const bcrypt = require("bcryptjs"); | |
const passport = require("passport"); | |
const _ = require("lodash"); | |
const LocalStrategy = require("passport-local").Strategy; | |
const GoogleStrategy = require("passport-google-oauth20").Strategy; | |
const FacebookStrategy = require("passport-facebook").Strategy; | |
const AmazonStrategy = require("passport-amazon").Strategy; | |
const GitHubStrategy = require("passport-github").Strategy; | |
const TwitterStrategy = require("passport-twitter").Strategy; | |
const SpotifyStrategy = require("passport-spotify").Strategy; | |
const TwitchStrategy = require("passport-twitch-new").Strategy; | |
const User = require("../models/Users"); | |
const credentials = require("./credentials"); | |
const findByEmailOrCreate = (email, req, profile, done) => { | |
// third party auth provider requires slightly different handling of passing the referral code | |
const raw_referred_by = req.query.state || req.session.state; | |
const referred_by = _.isEmpty(req.query) ? "" : JSON.parse(raw_referred_by.replace(/"/g, '"')).referral_code; | |
const name = profile.displayName || profile.username || profile.display_name; | |
User.findOne({ email: email }).then(user => { | |
if (!user) { | |
const newUser = new User({ | |
name, | |
email, | |
email_is_verified: true, | |
referred_by: referred_by, | |
third_party_auth: [ | |
{ | |
provider_name: profile.provider, | |
provider_id: profile.id, | |
provider_data: profile | |
} | |
] | |
}); | |
newUser | |
.save() | |
.then(user => { | |
return done(null, user); | |
}) | |
.catch(err => { | |
return done(null, false); | |
}); | |
} else { | |
// ToDo: Check for third_party_auth if we already have a entry | |
// in our third_party_auth array, if not push into it | |
return done(null, user); | |
} | |
}); | |
}; | |
passport.serializeUser((user, done) => { | |
done(null, user.id); | |
}); | |
passport.deserializeUser((id, done) => { | |
User.findById(id, (err, user) => { | |
done(err, user); | |
}); | |
}); | |
// Local Strategy | |
passport.use( | |
new LocalStrategy({ usernameField: "email" }, (email, password, done) => { | |
// Match User | |
User.findOne({ email: email }) | |
.then(user => { | |
// Create new User | |
if (!user) { | |
const newUser = new User({ email, password }); | |
// Hash password before saving in database | |
bcrypt.genSalt(10, (err, salt) => { | |
bcrypt.hash(newUser.password, salt, (err, hash) => { | |
if (err) throw err; | |
newUser.password = hash; | |
newUser | |
.save() | |
.then(user => { | |
return done(null, user); | |
}) | |
.catch(err => { | |
return done(null, false, { message: err }); | |
}); | |
}); | |
}); | |
// Return other user | |
} else { | |
// Match password | |
bcrypt.compare(password, user.password, (err, isMatch) => { | |
if (err) throw err; | |
if (isMatch) { | |
return done(null, user); | |
} else { | |
return done(null, false, { message: "Wrong password" }); | |
} | |
}); | |
} | |
}) | |
.catch(err => { | |
return done(null, false, { message: err }); | |
}); | |
}) | |
); | |
// Google Strategy | |
passport.use( | |
new GoogleStrategy( | |
{ | |
clientID: credentials.GOOGLE.client_id, | |
clientSecret: credentials.GOOGLE.client_secret, | |
callbackURL: "/api/auth/google/callback", | |
passReqToCallback: true | |
}, | |
(req, accessToken, refreshToken, profile, done) => { | |
const email = profile.emails.filter(email => email.verified)[0].value; | |
findByEmailOrCreate(email, req, profile, done); | |
} | |
) | |
); | |
// Facebook Strategy | |
passport.use( | |
new FacebookStrategy( | |
{ | |
clientID: credentials.FACEBOOK.client_id, | |
clientSecret: credentials.FACEBOOK.client_secret, | |
callbackURL: "/api/auth/facebook/callback", | |
passReqToCallback: true, | |
profileFields: [ | |
"id", | |
"email", | |
"gender", | |
"link", | |
"locale", | |
"name", | |
"displayName", | |
"timezone", | |
"updated_time", | |
"verified" | |
] | |
}, | |
function(req, accessToken, refreshToken, profile, done) { | |
const email = profile.emails[0].value; | |
findByEmailOrCreate(email, req, profile, done); | |
} | |
) | |
); | |
// Github Strategy | |
passport.use( | |
new GitHubStrategy( | |
{ | |
clientID: credentials.GITHUB.client_id, | |
clientSecret: credentials.GITHUB.client_secret, | |
callbackURL: "/api/auth/github/callback", | |
passReqToCallback: true, | |
scope: "user:email" | |
}, | |
function(req, accessToken, refreshToken, profile, done) { | |
const email = profile.emails.filter(email => email.verified && email.primary)[0].value; | |
findByEmailOrCreate(email, req, profile, done); | |
} | |
) | |
); | |
// Amazon Strategy | |
passport.use( | |
new AmazonStrategy( | |
{ | |
clientID: credentials.AMAZON.client_id, | |
clientSecret: credentials.AMAZON.client_secret, | |
callbackURL: "/api/auth/amazon/callback", | |
passReqToCallback: true | |
}, | |
function(req, accessToken, refreshToken, profile, done) { | |
const email = profile.emails[0].value; | |
findByEmailOrCreate(email, req, profile, done); | |
} | |
) | |
); | |
// Twitter Strategy | |
passport.use( | |
new TwitterStrategy( | |
{ | |
consumerKey: credentials.TWITTER.client_id, | |
consumerSecret: credentials.TWITTER.client_secret, | |
userProfileURL: "https://api.twitter.com/1.1/account/verify_credentials.json?include_email=true", | |
callbackURL: "/api/auth/twitter/callback", | |
passReqToCallback: true | |
}, | |
function(req, accessToken, refreshToken, profile, done) { | |
const email = profile.emails[0].value; | |
findByEmailOrCreate(email, req, profile, done); | |
} | |
) | |
); | |
// Sportif Strategy | |
passport.use( | |
new SpotifyStrategy( | |
{ | |
clientID: credentials.SPOTIFY.client_id, | |
clientSecret: credentials.SPOTIFY.client_secret, | |
callbackURL: "/api/auth/spotify/callback", | |
passReqToCallback: true | |
}, | |
function(req, accessToken, refreshToken, profile, done) { | |
const email = profile.emails[0].value; | |
findByEmailOrCreate(email, req, profile, done); | |
} | |
) | |
); | |
// TWITCH Strategy | |
passport.use( | |
new TwitchStrategy( | |
{ | |
clientID: credentials.TWITCH.client_id, | |
clientSecret: credentials.TWITCH.client_secret, | |
callbackURL: "/api/auth/twitch/callback", | |
passReqToCallback: true | |
}, | |
function(req, accessToken, refreshToken, profile, done) { | |
const email = profile.email; | |
findByEmailOrCreate(email, req, profile, done); | |
} | |
) | |
); | |
module.exports = passport; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment