diff --git a/app.js b/app.js index 8d866324d..adc184c2e 100644 --- a/app.js +++ b/app.js @@ -149,19 +149,23 @@ app.use((req, res, next) => { const isSafeRedirect = (url) => /^\/[a-zA-Z0-9/_-]*$/.test(url); app.use((req, res, next) => { // After successful login, redirect back to the intended page - if (!req.user && req.path !== '/login' && req.path !== '/signup' && !req.path.match(/^\/auth/) && !req.path.match(/\./)) { + if (!req.user && req.path !== '/login' && req.path !== '/signup' && !req.path.startsWith('/auth') && !req.path.includes('.')) { const returnTo = req.originalUrl; if (isSafeRedirect(returnTo)) { req.session.returnTo = returnTo; } else { req.session.returnTo = '/'; } - } else if (req.user && (req.path === '/account' || req.path.match(/^\/api/))) { + } else if (req.user && (req.path === '/account' || req.path.startsWith('/api'))) { const returnTo = req.originalUrl; if (isSafeRedirect(returnTo)) { req.session.returnTo = returnTo; + if (req.path.startsWith('/api/') && !req.session.baseReturnTo) { + req.session.baseReturnTo = '/api'; + } } else { req.session.returnTo = '/'; + req.session.baseReturnTo = '/'; } } next(); @@ -268,14 +272,15 @@ app.get('/auth/failure', (req, res) => { if (!hasErrorFlash) { req.flash('errors', { msg: 'Authentication failed or provider account is already linked.' }); } - const { returnTo } = req.session; + const { returnTo, baseReturnTo } = req.session; req.session.returnTo = undefined; - // Prevent infinite loop: if returnTo is the current URL or an /auth/ route, redirect to / - if (!returnTo || !isSafeRedirect(returnTo) || returnTo === req.originalUrl || /^\/auth\//.test(returnTo)) { + req.session.baseReturnTo = undefined; + const redirectTarget = baseReturnTo || returnTo; + + if (!redirectTarget || !isSafeRedirect(redirectTarget) || redirectTarget === req.originalUrl || redirectTarget.startsWith('/auth/')) { res.redirect('/'); - } else { - res.redirect(returnTo); } + res.redirect(redirectTarget); }); /** diff --git a/config/passport.js b/config/passport.js index db09d4c1e..4fafc0660 100644 --- a/config/passport.js +++ b/config/passport.js @@ -147,6 +147,11 @@ async function saveOAuth2UserTokens(req, accessToken, refreshToken, accessTokenE /** * Sign in with Facebook. */ + +FacebookStrategy.prototype.authorizationParams = function () { + return { auth_type: 'rerequest' }; +}; + passport.use( new FacebookStrategy( { @@ -154,6 +159,7 @@ passport.use( clientSecret: process.env.FACEBOOK_SECRET, callbackURL: `${process.env.BASE_URL}/auth/facebook/callback`, profileFields: ['name', 'email', 'link', 'locale', 'timezone', 'gender'], + scope: ['public_profile', 'email'], state: generateState(), passReqToCallback: true, }, @@ -197,6 +203,12 @@ passport.use( }); return done(null, false); } + if (normalizedEmail === undefined) { + req.flash('errors', { + msg: `Unable to sign in with Facebook. No email address was provided for account creation.`, + }); + return done(null, false); + } const user = new User(); user.email = normalizedEmail; user.facebook = profile.id;