UNPKG

@datawheel/canon-core

Version:

Reusable React environment and components for creating visualization engines.

144 lines (129 loc) 4.23 kB
let socialRedirectUrl = process.env.CANON_SOCIAL_REDIRECT || "/"; socialRedirectUrl = !socialRedirectUrl.endsWith("/") ? `${socialRedirectUrl}/` : socialRedirectUrl; const parseEmail = p => p.emails && p.emails.length ? p.emails[0].value : null; const addEmail = (userData, p) => { const socialEmail = parseEmail(p); return socialEmail ? {...userData, socialEmail} : userData; }; const config = { facebook: [ { clientID: process.env.CANON_FACEBOOK_API, clientSecret: process.env.CANON_FACEBOOK_SECRET, callbackURL: `${socialRedirectUrl}auth/facebook/callback`, profileFields: ["id", "displayName", "photos", "email", "birthday", "cover"], scope: ["public_profile", "email"] }, p => { const userData = { id: `fb${p.id}`, name: p.displayName, facebook: p.id, username: p.displayName.toLowerCase().replace(" ", "-") }; return addEmail(userData, p); } ], google: [ { clientID: process.env.CANON_GOOGLE_API, clientSecret: process.env.CANON_GOOGLE_SECRET, callbackURL: `${socialRedirectUrl}auth/google/callback`, scope: ["profile", "email"], module: "google-oauth20" }, p => { const userData = { id: `goog${p.id}`, name: p.displayName, google: p.id, username: p.displayName.toLowerCase().replace(" ", "-") }; return addEmail(userData, p); } ], github: [ { clientID: process.env.CANON_GITHUB_API, clientSecret: process.env.CANON_GITHUB_SECRET, callbackURL: `${socialRedirectUrl}auth/github/callback`, scope: ["user", "user:email"] }, p => { const userData = { id: `gh${p.id}`, name: p.displayName, github: p.id, username: p.displayName.toLowerCase().replace(" ", "-") }; return addEmail(userData, p); } ], instagram: [ { clientID: process.env.CANON_INSTAGRAM_API, clientSecret: process.env.CANON_INSTAGRAM_SECRET, callbackURL: `${socialRedirectUrl}auth/instagram/callback` }, p => ({ id: `ig${p.id}`, name: p.displayName, instagram: p.id, username: `${p.displayName.toLowerCase().replace(" ", "-")}-${p.id}` }) ], linkedin: [ { clientID: process.env.CANON_LINKEDIN_API, clientSecret: process.env.CANON_LINKEDIN_SECRET, callbackURL: `${socialRedirectUrl}auth/linkedin/callback`, module: "linkedin-oauth2", scope: ["r_basicprofile", "r_emailaddress"] }, p => { const userData = { id: `li${p.id}`, name: p.displayName, linkedin: p.id, username: p.displayName.toLowerCase().replace(" ", "-") }; return addEmail(userData, p); } ], twitter: [ { consumerKey: process.env.CANON_TWITTER_API, consumerSecret: process.env.CANON_TWITTER_SECRET, callbackURL: `${socialRedirectUrl}auth/twitter/callback`, includeEmail: true }, p => { const userData = { id: `t${p.id}`, name: p.displayName, twitter: p.username, username: p.username }; return addEmail(userData, p); } ] }; module.exports = function(app, service) { const {db, passport, social} = app.settings; const [strat, query] = config[service]; social.push(service); const servicePackage = strat.module || service; const Strategy = require(`passport-${servicePackage}`).Strategy; passport.use(new Strategy(strat, (accessToken, refreshToken, profile, done) => { const searchQuery = query(profile); // update the user if s/he exists or add a new user return db.users.upsert(searchQuery) .then(() => db.users.findOne({where: {id: searchQuery.id}, raw: true}) .catch(err => console.log(err)) .then((user, err) => done(err, user))); })); const authOptions = strat.scope ? {scope: strat.scope} : null; app.get(`/auth/${service}/`, passport.authenticate(service, authOptions)); app.get(`/auth/${service}/callback`, passport.authenticate(service, {failureRedirect: "/"}), (req, res) => res.redirect(socialRedirectUrl), err => console.log(`Error with ${service} login:`, err)); };