| 
									
										
										
										
											2016-02-11 22:33:54 -08:00
										 |  |  | import passport from 'passport'; | 
					
						
							| 
									
										
										
										
											2019-02-18 19:32:49 +00:00
										 |  |  | // eslint-disable-next-line
 | 
					
						
							| 
									
										
										
										
											2018-10-24 00:24:48 +01:00
										 |  |  | import { | 
					
						
							| 
									
										
										
										
											2019-02-18 19:32:49 +00:00
										 |  |  |   // prettier ignore
 | 
					
						
							| 
									
										
										
										
											2018-10-24 00:24:48 +01:00
										 |  |  |   PassportConfigurator | 
					
						
							|  |  |  | } from '@freecodecamp/loopback-component-passport'; | 
					
						
							| 
									
										
										
										
											2018-05-19 21:21:49 +05:30
										 |  |  | import url from 'url'; | 
					
						
							| 
									
										
										
										
											2018-06-01 02:29:27 +05:30
										 |  |  | import dedent from 'dedent'; | 
					
						
							| 
									
										
										
										
											2016-02-11 22:33:54 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-04 21:10:12 +00:00
										 |  |  | import { getUserById } from './utils/user-stats'; | 
					
						
							| 
									
										
										
										
											2019-02-04 11:42:31 +00:00
										 |  |  | import { homeLocation } from '../../config/env'; | 
					
						
							| 
									
										
										
										
											2018-10-24 00:24:48 +01:00
										 |  |  | import passportProviders from './passport-providers'; | 
					
						
							| 
									
										
										
										
											2019-02-20 23:07:12 +00:00
										 |  |  | import { setAccessTokenToResponse } from './utils/getSetAccessToken'; | 
					
						
							| 
									
										
										
										
											2018-10-24 00:24:48 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-11 22:33:54 -08:00
										 |  |  | const passportOptions = { | 
					
						
							|  |  |  |   emailOptional: true, | 
					
						
							| 
									
										
										
										
											2017-07-13 11:39:07 -07:00
										 |  |  |   profileToUser: null | 
					
						
							| 
									
										
										
										
											2016-02-11 22:33:54 -08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PassportConfigurator.prototype.init = function passportInit(noSession) { | 
					
						
							|  |  |  |   this.app.middleware('session:after', passport.initialize()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (noSession) { | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   this.app.middleware('session:after', passport.session()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Serialization and deserialization is only required if passport session is
 | 
					
						
							|  |  |  |   // enabled
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-04 21:10:12 +00:00
										 |  |  |   passport.serializeUser((user, done) => done(null, user.id)); | 
					
						
							| 
									
										
										
										
											2016-02-11 22:33:54 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-04 21:10:12 +00:00
										 |  |  |   passport.deserializeUser(async (id, done) => { | 
					
						
							|  |  |  |     const user = await getUserById(id).catch(done); | 
					
						
							|  |  |  |     return done(null, user); | 
					
						
							| 
									
										
										
										
											2016-02-11 22:33:54 -08:00
										 |  |  |   }); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-23 16:29:26 +01:00
										 |  |  | export function setupPassport(app) { | 
					
						
							| 
									
										
										
										
											2016-02-11 22:33:54 -08:00
										 |  |  |   const configurator = new PassportConfigurator(app); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   configurator.setupModels({ | 
					
						
							|  |  |  |     userModel: app.models.user, | 
					
						
							|  |  |  |     userIdentityModel: app.models.userIdentity, | 
					
						
							|  |  |  |     userCredentialModel: app.models.userCredential | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   configurator.init(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Object.keys(passportProviders).map(function(strategy) { | 
					
						
							| 
									
										
										
										
											2018-05-19 21:21:49 +05:30
										 |  |  |     let config = passportProviders[strategy]; | 
					
						
							| 
									
										
										
										
											2016-02-11 22:33:54 -08:00
										 |  |  |     config.session = config.session !== false; | 
					
						
							| 
									
										
										
										
											2018-05-20 00:50:55 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-20 13:40:15 +05:30
										 |  |  |     config.customCallback = !config.useCustomCallback | 
					
						
							| 
									
										
										
										
											2018-05-20 00:50:55 +05:30
										 |  |  |       ? null | 
					
						
							| 
									
										
										
										
											2018-10-24 00:24:48 +01:00
										 |  |  |       : createPassportCallbackAuthenticator(strategy, config); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     configurator.configureProvider(strategy, { | 
					
						
							|  |  |  |       ...config, | 
					
						
							|  |  |  |       ...passportOptions | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2016-02-11 22:33:54 -08:00
										 |  |  |   }); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-10-24 00:24:48 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-30 18:17:07 -03:00
										 |  |  | export const saveResponseAuthCookies = () => { | 
					
						
							|  |  |  |   return (req, res, next) => { | 
					
						
							|  |  |  |     const user = req.user; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!user) { | 
					
						
							|  |  |  |       return res.redirect('/signin'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const { accessToken } = user; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-20 23:07:12 +00:00
										 |  |  |     setAccessTokenToResponse({ accessToken }, req, res); | 
					
						
							| 
									
										
										
										
											2018-10-30 18:17:07 -03:00
										 |  |  |     return next(); | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export const loginRedirect = () => { | 
					
						
							|  |  |  |   return (req, res) => { | 
					
						
							|  |  |  |     const successRedirect = req => { | 
					
						
							|  |  |  |       if (!!req && req.session && req.session.returnTo) { | 
					
						
							|  |  |  |         delete req.session.returnTo; | 
					
						
							|  |  |  |         return `${homeLocation}/welcome`; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       return `${homeLocation}/welcome`; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     let redirect = url.parse(successRedirect(req), true); | 
					
						
							|  |  |  |     delete redirect.search; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     redirect = url.format(redirect); | 
					
						
							|  |  |  |     return res.redirect(redirect); | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-24 00:24:48 +01:00
										 |  |  | export const createPassportCallbackAuthenticator = (strategy, config) => ( | 
					
						
							|  |  |  |   req, | 
					
						
							|  |  |  |   res, | 
					
						
							|  |  |  |   next | 
					
						
							|  |  |  | ) => { | 
					
						
							|  |  |  |   return passport.authenticate( | 
					
						
							|  |  |  |     strategy, | 
					
						
							|  |  |  |     { session: false }, | 
					
						
							|  |  |  |     (err, user, userInfo) => { | 
					
						
							|  |  |  |       if (err) { | 
					
						
							|  |  |  |         return next(err); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (!user || !userInfo) { | 
					
						
							|  |  |  |         return res.redirect('/signin'); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-03-04 21:12:51 +00:00
										 |  |  |       const redirect = `${homeLocation}/welcome`; | 
					
						
							| 
									
										
										
										
											2018-10-24 00:24:48 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |       const { accessToken } = userInfo; | 
					
						
							|  |  |  |       const { provider } = config; | 
					
						
							|  |  |  |       if (accessToken && accessToken.id) { | 
					
						
							|  |  |  |         if (provider === 'auth0') { | 
					
						
							|  |  |  |           req.flash( | 
					
						
							|  |  |  |             'success', | 
					
						
							|  |  |  |             dedent`
 | 
					
						
							|  |  |  |               Success! You have signed in to your account. Happy Coding! | 
					
						
							|  |  |  |             `
 | 
					
						
							|  |  |  |           ); | 
					
						
							|  |  |  |         } else if (user.email) { | 
					
						
							|  |  |  |           req.flash( | 
					
						
							|  |  |  |             'info', | 
					
						
							|  |  |  |             dedent`
 | 
					
						
							|  |  |  | We are moving away from social authentication for privacy reasons. Next time | 
					
						
							|  |  |  | we recommend using your email address: ${user.email} to sign in instead. | 
					
						
							|  |  |  |             `
 | 
					
						
							|  |  |  |           ); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-02-20 23:07:12 +00:00
										 |  |  |         setAccessTokenToResponse({ accessToken }, req, res); | 
					
						
							| 
									
										
										
										
											2018-10-24 00:24:48 +01:00
										 |  |  |         req.login(user); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-03-04 21:12:51 +00:00
										 |  |  |       return res.redirectWithFlash(redirect); | 
					
						
							| 
									
										
										
										
											2018-10-24 00:24:48 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |   )(req, res, next); | 
					
						
							|  |  |  | }; |