forked from kriasoft/graphql-starter-kit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
passport.js
112 lines (103 loc) · 3.23 KB
/
passport.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/**
* Node.js API Starter Kit (https://reactstarter.com/nodejs)
*
* Copyright © 2016-present Kriasoft, LLC. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE.txt file in the root directory of this source tree.
*/
/* @flow */
/* eslint-disable global-require, no-param-reassign, no-underscore-dangle */
import passport from 'passport';
import User from './models/User';
passport.serializeUser((user, done) => {
done(null, user.id);
});
passport.deserializeUser((id, done) => {
User.findOne({ id }).then(user => done(null, user || null), done);
});
const strategies = [
{
name: 'Facebook',
provider: 'facebook',
Strategy: require('passport-facebook').Strategy,
options: {
clientID: process.env.FACEBOOK_ID,
clientSecret: process.env.FACEBOOK_SECRET,
profileFields: ['name', 'email', 'link', 'locale', 'timezone'],
},
readProfile(profile) {
return {
email: profile._json.email,
};
},
},
{
name: 'Google',
provider: 'google',
Strategy: require('passport-google-oauth').OAuth2Strategy,
options: {
clientID: process.env.GOOGLE_ID,
clientSecret: process.env.GOOGLE_SECRET,
},
readProfile(profile) {
return {
email: profile.emails[0].value,
};
},
},
{
name: 'Twitter',
provider: 'twitter',
Strategy: require('passport-twitter').Strategy,
options: {
consumerKey: process.env.TWITTER_KEY,
consumerSecret: process.env.TWITTER_SECRET,
},
readProfile(profile) {
return {
email: `${profile.username}@twitter.com`,
};
},
},
];
strategies.forEach(({ name, provider, Strategy, options, readProfile }) => {
passport.use(new Strategy({
...options,
callbackURL: `/login/${provider}/return`,
passReqToCallback: true,
}, async (req, accessToken, refreshToken, profile, done) => {
try {
const { email } = readProfile(profile);
const claims = [
{ type: `urn:${provider}:access_token`, value: accessToken },
{ type: `urn:${provider}:refresh_token`, value: refreshToken },
];
let user = await User.findOneByLogin(provider, profile.id);
if (req.user) {
if (user && req.user.id === user.id) {
done(null, user);
} else if (user) {
req.app.locals.error = `There is already a ${name} account that belongs to you. Sign in with that account or delete it, then link it with your current account.`;
done();
} else {
await User.setClaims(req.user.id, provider, profile.id, claims);
req.app.locals.info = `${name} account has been linked.`;
done(null, await User.findOne('id', req.user.id));
}
} else if (user) {
done(null, user);
} else if (await User.any({ email })) {
req.app.locals.error = `There is already an account using this email address. Sign in to that account and link it with ${name} manually from Account Settings.`;
done();
} else {
user = await User.create({ email });
await User.setClaims(user.id, provider, profile.id, claims);
done(null, user);
}
} catch (err) {
done(err);
}
}));
});
export default passport;