diff --git a/README.md b/README.md index 9fd12456..74b9c9fd 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,8 @@ This project is currently in development! It will be announced when there is a ( S3_BUCKET= GITHUB_ID= GITHUB_SECRET= + GOOGLE_ID= (use google+ api) + GOOGLE_SECRET= (use google+ api) MAILGUN_KEY= ``` diff --git a/client/images/google.svg b/client/images/google.svg new file mode 100644 index 00000000..542fea64 --- /dev/null +++ b/client/images/google.svg @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/client/modules/User/components/GoogleButton.jsx b/client/modules/User/components/GoogleButton.jsx new file mode 100644 index 00000000..ed2eb4d9 --- /dev/null +++ b/client/modules/User/components/GoogleButton.jsx @@ -0,0 +1,24 @@ +import InlineSVG from 'react-inlinesvg'; +import PropTypes from 'prop-types'; +import React from 'react'; + +// const googleUrl = require('../../../images/google.svg'); +import googleUrl from '../../../images/google.svg'; + +function GoogleButton(props) { + return ( + + + {props.buttonText} + + ); +} + +GoogleButton.propTypes = { + buttonText: PropTypes.string.isRequired +}; + +export default GoogleButton; diff --git a/client/modules/User/pages/LoginView.jsx b/client/modules/User/pages/LoginView.jsx index 5183c76e..59d118c6 100644 --- a/client/modules/User/pages/LoginView.jsx +++ b/client/modules/User/pages/LoginView.jsx @@ -8,6 +8,8 @@ import { validateAndLoginUser } from '../actions'; import LoginForm from '../components/LoginForm'; import { validateLogin } from '../../../utils/reduxFormUtils'; import GithubButton from '../components/GithubButton'; +import GoogleButton from '../components/GoogleButton'; + const exitUrl = require('../../../images/exit.svg'); const logoUrl = require('../../../images/p5js-logo.svg'); @@ -51,6 +53,7 @@ class LoginView extends React.Component {

Or

+

Don't have an account?  Sign Up diff --git a/client/styles/components/_github-button.scss b/client/styles/components/_github-button.scss index 1adf85d0..2b6662fe 100644 --- a/client/styles/components/_github-button.scss +++ b/client/styles/components/_github-button.scss @@ -21,3 +21,32 @@ .github-icon { margin-right: #{10 / $base-font-size}rem; } + + +.google-button { + @include themify() { + @extend %button; + & path { + color: getThemifyVariable('primary-text-color'); + } + &:hover path, &:active path { + fill: $white; + } + &:hover, &:active { + background-color: getThemifyVariable('secondary-text-color'); + border-color: getThemifyVariable('secondary-text-color'); + } + } + margin-top: 4px; + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + width: #{300 / $base-font-size}rem; +} + +.google-icon { + width: 32px; + height: 32px; + margin-right: #{10 / $base-font-size}rem; +} \ No newline at end of file diff --git a/package.json b/package.json index dda8be66..661fc12a 100644 --- a/package.json +++ b/package.json @@ -99,6 +99,7 @@ "nodemailer-mailgun-transport": "^1.2.2", "passport": "^0.3.2", "passport-github": "^1.1.0", + "passport-google-oauth20": "^1.0.0", "passport-local": "^1.0.0", "pretty-bytes": "^3.0.1", "primer-tooltips": "^1.4.1", diff --git a/server/config/passport.js b/server/config/passport.js index 769a08de..efeeefd0 100644 --- a/server/config/passport.js +++ b/server/config/passport.js @@ -4,6 +4,8 @@ const lodash = require('lodash'); const passport = require('passport'); const GitHubStrategy = require('passport-github').Strategy; const LocalStrategy = require('passport-local').Strategy; +const GoogleStrategy = require('passport-google-oauth20').Strategy; + passport.serializeUser((user, done) => { done(null, user.id); @@ -99,3 +101,46 @@ passport.use(new GitHubStrategy({ }); }); })); + +/** + * Sign in with Google. + */ +passport.use(new GoogleStrategy({ + clientID: process.env.GOOGLE_ID, + clientSecret: process.env.GOOGLE_SECRET, + callbackURL: '/auth/google/callback', + passReqToCallback: true, + scope: ['email'], +}, (req, accessToken, refreshToken, profile, done) => { + User.findOne({ google: profile._json.emails[0].value }, (findByGoogleErr, existingUser) => { + if (existingUser) { + done(null, existingUser); + return; + } + + const primaryEmail = profile._json.emails[0].value; + + User.findOne({ + email: primaryEmail, + }, (findByEmailErr, existingEmailUser) => { + if (existingEmailUser) { + existingEmailUser.email = existingEmailUser.email || primaryEmail; + existingEmailUser.google = profile._json.emails[0].value; + existingEmailUser.username = existingEmailUser.username || profile._json.emails[0].value; + existingEmailUser.tokens.push({ kind: 'google', accessToken }); + existingEmailUser.name = existingEmailUser.name || profile._json.displayName; + existingEmailUser.verified = User.EmailConfirmation.Verified; + existingEmailUser.save(saveErr => done(null, existingEmailUser)); + } else { + const user = new User(); + user.email = primaryEmail; + user.google = profile._json.emails[0].value; + user.username = profile._json.emails[0].value; + user.tokens.push({ kind: 'google', accessToken }); + user.name = profile._json.displayName; + user.verified = User.EmailConfirmation.Verified; + user.save(saveErr => done(null, user)); + } + }); + }); +})); diff --git a/server/server.js b/server/server.js index 7cbaa421..102bdfd7 100644 --- a/server/server.js +++ b/server/server.js @@ -96,6 +96,11 @@ app.get('/auth/github/callback', passport.authenticate('github', { failureRedire res.redirect('/'); }); +app.get('/auth/google', passport.authenticate('google')); +app.get('/auth/google/callback', passport.authenticate('google', { failureRedirect: '/login' }), (req, res) => { + res.redirect('/'); +}); + // configure passport require('./config/passport'); // const passportConfig = require('./config/passport');