Search for existing user account using Github emails (#337)
* Tries to match user account from list of emails in Github API Requests the 'user:email' scope from Github which returns the private emails associated with the user's account. * Centres GitHub button in layout
This commit is contained in:
parent
4f531c14f4
commit
7be45ce875
4 changed files with 42 additions and 9 deletions
|
@ -7,6 +7,7 @@ import axios from 'axios';
|
|||
import { updateSettings } from '../actions';
|
||||
import AccountForm from '../components/AccountForm';
|
||||
import { validateSettings } from '../../../utils/reduxFormUtils';
|
||||
import GithubButton from '../components/GithubButton';
|
||||
|
||||
const exitUrl = require('../../../images/exit.svg');
|
||||
const logoUrl = require('../../../images/p5js-logo.svg');
|
||||
|
@ -41,8 +42,8 @@ class AccountView extends React.Component {
|
|||
<div className="form-container__content">
|
||||
<h2 className="form-container__title">My Account</h2>
|
||||
<AccountForm {...this.props} />
|
||||
{/* <h2 className="form-container__divider">Or</h2>
|
||||
<GithubButton buttonText="Login with Github" /> */}
|
||||
<h2 className="form-container__divider">Or</h2>
|
||||
<GithubButton buttonText="Login with Github" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -5,7 +5,8 @@ import InlineSVG from 'react-inlinesvg';
|
|||
import { validateAndLoginUser } from '../actions';
|
||||
import LoginForm from '../components/LoginForm';
|
||||
import { validateLogin } from '../../../utils/reduxFormUtils';
|
||||
// import GithubButton from '../components/GithubButton';
|
||||
import GithubButton from '../components/GithubButton';
|
||||
|
||||
const exitUrl = require('../../../images/exit.svg');
|
||||
const logoUrl = require('../../../images/p5js-logo.svg');
|
||||
|
||||
|
@ -39,8 +40,8 @@ class LoginView extends React.Component {
|
|||
<div className="form-container__content">
|
||||
<h2 className="form-container__title">Log In</h2>
|
||||
<LoginForm {...this.props} />
|
||||
{/* <h2 className="form-container__divider">Or</h2>
|
||||
<GithubButton buttonText="Login with Github" /> */}
|
||||
<h2 className="form-container__divider">Or</h2>
|
||||
<GithubButton buttonText="Login with Github" />
|
||||
<p className="form__navigation-options">
|
||||
Don't have an account?
|
||||
<Link className="form__signup-button" to="/signup">Sign Up</Link>
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.form-container__title {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import User from '../models/user';
|
||||
|
||||
const lodash = require('lodash');
|
||||
const passport = require('passport');
|
||||
const GitHubStrategy = require('passport-github').Strategy;
|
||||
const LocalStrategy = require('passport-local').Strategy;
|
||||
|
@ -33,6 +34,28 @@ passport.use(new LocalStrategy({ usernameField: 'email' }, (email, password, don
|
|||
.catch(err => done(null, false, { msg: err }));
|
||||
}));
|
||||
|
||||
/*
|
||||
Input:
|
||||
[
|
||||
{ value: 'email@example.com', primary: false, verified: true },
|
||||
{ value: 'unverified@example.com', primary: false, verified: false }
|
||||
]
|
||||
|
||||
Output:
|
||||
['email@example.com']
|
||||
*/
|
||||
const getVerifiedEmails = githubEmails => (
|
||||
(githubEmails || [])
|
||||
.filter(item => item.verified === true)
|
||||
.map(item => item.value)
|
||||
);
|
||||
|
||||
const getPrimaryEmail = githubEmails => (
|
||||
(
|
||||
lodash.find(githubEmails, { primary: true }) || {}
|
||||
).value
|
||||
);
|
||||
|
||||
/**
|
||||
* Sign in with GitHub.
|
||||
*/
|
||||
|
@ -40,16 +63,23 @@ passport.use(new GitHubStrategy({
|
|||
clientID: process.env.GITHUB_ID,
|
||||
clientSecret: process.env.GITHUB_SECRET,
|
||||
callbackURL: '/auth/github/callback',
|
||||
passReqToCallback: true
|
||||
passReqToCallback: true,
|
||||
scope: ['user:email'],
|
||||
}, (req, accessToken, refreshToken, profile, done) => {
|
||||
User.findOne({ github: profile.id }, (findByGithubErr, existingUser) => {
|
||||
if (existingUser) {
|
||||
done(null, existingUser);
|
||||
return;
|
||||
}
|
||||
User.findOne({ email: profile._json.email }, (findByEmailErr, existingEmailUser) => {
|
||||
|
||||
const emails = getVerifiedEmails(profile.emails);
|
||||
const primaryEmail = getPrimaryEmail(profile.emails);
|
||||
|
||||
User.findOne({
|
||||
email: { $in: emails },
|
||||
}, (findByEmailErr, existingEmailUser) => {
|
||||
if (existingEmailUser) {
|
||||
existingEmailUser.email = existingEmailUser.email || profile._json.email;
|
||||
existingEmailUser.email = existingEmailUser.email || primaryEmail;
|
||||
existingEmailUser.github = profile.id;
|
||||
existingEmailUser.username = existingEmailUser.username || profile.username;
|
||||
existingEmailUser.tokens.push({ kind: 'github', accessToken });
|
||||
|
@ -57,7 +87,7 @@ passport.use(new GitHubStrategy({
|
|||
existingEmailUser.save(saveErr => done(null, existingEmailUser));
|
||||
} else {
|
||||
const user = new User();
|
||||
user.email = profile._json.email;
|
||||
user.email = primaryEmail;
|
||||
user.github = profile.id;
|
||||
user.username = profile.username;
|
||||
user.tokens.push({ kind: 'github', accessToken });
|
||||
|
|
Loading…
Reference in a new issue