passport.js (3947B)
1 /** 2 * React Starter Kit (https://www.reactstarterkit.com/) 3 * 4 * Copyright © 2014-present Kriasoft, LLC. All rights reserved. 5 * 6 * This source code is licensed under the MIT license found in the 7 * LICENSE.txt file in the root directory of this source tree. 8 */ 9 10 /** 11 * Passport.js reference implementation. 12 * The database schema used in this sample is available at 13 * https://github.com/membership/membership.db/tree/master/postgres 14 */ 15 16 import passport from 'passport'; 17 import { Strategy as FacebookStrategy } from 'passport-facebook'; 18 import { User, UserLogin, UserClaim, UserProfile } from '../data/models'; 19 import { auth as config } from '../config'; 20 21 /** 22 * Sign in with Facebook. 23 */ 24 passport.use(new FacebookStrategy({ 25 clientID: config.facebook.id, 26 clientSecret: config.facebook.secret, 27 callbackURL: '/login/facebook/return', 28 profileFields: ['name', 'email', 'link', 'locale', 'timezone'], 29 passReqToCallback: true, 30 }, (req, accessToken, refreshToken, profile, done) => { 31 /* eslint-disable no-underscore-dangle */ 32 const loginName = 'facebook'; 33 const claimType = 'urn:facebook:access_token'; 34 const fooBar = async () => { 35 if (req.user) { 36 const userLogin = await UserLogin.findOne({ 37 attributes: ['name', 'key'], 38 where: { name: loginName, key: profile.id }, 39 }); 40 if (userLogin) { 41 // There is already a Facebook account that belongs to you. 42 // Sign in with that account or delete it, then link it with your current account. 43 done(); 44 } else { 45 const user = await User.create({ 46 id: req.user.id, 47 email: profile._json.email, 48 logins: [ 49 { name: loginName, key: profile.id }, 50 ], 51 claims: [ 52 { type: claimType, value: profile.id }, 53 ], 54 profile: { 55 displayName: profile.displayName, 56 gender: profile._json.gender, 57 picture: `https://graph.facebook.com/${profile.id}/picture?type=large`, 58 }, 59 }, { 60 include: [ 61 { model: UserLogin, as: 'logins' }, 62 { model: UserClaim, as: 'claims' }, 63 { model: UserProfile, as: 'profile' }, 64 ], 65 }); 66 done(null, { 67 id: user.id, 68 email: user.email, 69 }); 70 } 71 } else { 72 const users = await User.findAll({ 73 attributes: ['id', 'email'], 74 where: { '$logins.name$': loginName, '$logins.key$': profile.id }, 75 include: [ 76 { 77 attributes: ['name', 'key'], 78 model: UserLogin, 79 as: 'logins', 80 required: true, 81 }, 82 ], 83 }); 84 if (users.length) { 85 done(null, users[0]); 86 } else { 87 let user = await User.findOne({ where: { email: profile._json.email } }); 88 if (user) { 89 // There is already an account using this email address. Sign in to 90 // that account and link it with Facebook manually from Account Settings. 91 done(null); 92 } else { 93 user = await User.create({ 94 email: profile._json.email, 95 emailConfirmed: true, 96 logins: [ 97 { name: loginName, key: profile.id }, 98 ], 99 claims: [ 100 { type: claimType, value: accessToken }, 101 ], 102 profile: { 103 displayName: profile.displayName, 104 gender: profile._json.gender, 105 picture: `https://graph.facebook.com/${profile.id}/picture?type=large`, 106 }, 107 }, { 108 include: [ 109 { model: UserLogin, as: 'logins' }, 110 { model: UserClaim, as: 'claims' }, 111 { model: UserProfile, as: 'profile' }, 112 ], 113 }); 114 done(null, { 115 id: user.id, 116 email: user.email, 117 }); 118 } 119 } 120 } 121 }; 122 123 fooBar().catch(done); 124 })); 125 126 export default passport;