Skip to content

Instantly share code, notes, and snippets.

@FBosler
Last active March 10, 2020 08:25
Show Gist options
  • Save FBosler/ff8efceb2eac4dbef9e01c6ad651d43b to your computer and use it in GitHub Desktop.
Save FBosler/ff8efceb2eac4dbef9e01c6ad651d43b to your computer and use it in GitHub Desktop.
backend_ii_iii
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;
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;
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;
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;
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(/&#34;/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