Skip to content

Commit 8530fee

Browse files
authored
fix: Add missing email scope to FB integration, fix stuck auth loop
1 parent d365fec commit 8530fee

File tree

2 files changed

+24
-7
lines changed

2 files changed

+24
-7
lines changed

app.js

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -149,19 +149,23 @@ app.use((req, res, next) => {
149149
const isSafeRedirect = (url) => /^\/[a-zA-Z0-9/_-]*$/.test(url);
150150
app.use((req, res, next) => {
151151
// After successful login, redirect back to the intended page
152-
if (!req.user && req.path !== '/login' && req.path !== '/signup' && !req.path.match(/^\/auth/) && !req.path.match(/\./)) {
152+
if (!req.user && req.path !== '/login' && req.path !== '/signup' && !req.path.startsWith('/auth') && !req.path.includes('.')) {
153153
const returnTo = req.originalUrl;
154154
if (isSafeRedirect(returnTo)) {
155155
req.session.returnTo = returnTo;
156156
} else {
157157
req.session.returnTo = '/';
158158
}
159-
} else if (req.user && (req.path === '/account' || req.path.match(/^\/api/))) {
159+
} else if (req.user && (req.path === '/account' || req.path.startsWith('/api'))) {
160160
const returnTo = req.originalUrl;
161161
if (isSafeRedirect(returnTo)) {
162162
req.session.returnTo = returnTo;
163+
if (req.path.startsWith('/api/') && !req.session.baseReturnTo) {
164+
req.session.baseReturnTo = '/api';
165+
}
163166
} else {
164167
req.session.returnTo = '/';
168+
req.session.baseReturnTo = '/';
165169
}
166170
}
167171
next();
@@ -268,14 +272,15 @@ app.get('/auth/failure', (req, res) => {
268272
if (!hasErrorFlash) {
269273
req.flash('errors', { msg: 'Authentication failed or provider account is already linked.' });
270274
}
271-
const { returnTo } = req.session;
275+
const { returnTo, baseReturnTo } = req.session;
272276
req.session.returnTo = undefined;
273-
// Prevent infinite loop: if returnTo is the current URL or an /auth/ route, redirect to /
274-
if (!returnTo || !isSafeRedirect(returnTo) || returnTo === req.originalUrl || /^\/auth\//.test(returnTo)) {
277+
req.session.baseReturnTo = undefined;
278+
const redirectTarget = baseReturnTo || returnTo;
279+
280+
if (!redirectTarget || !isSafeRedirect(redirectTarget) || redirectTarget === req.originalUrl || redirectTarget.startsWith('/auth/')) {
275281
res.redirect('/');
276-
} else {
277-
res.redirect(returnTo);
278282
}
283+
res.redirect(redirectTarget);
279284
});
280285

281286
/**

config/passport.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,13 +147,19 @@ async function saveOAuth2UserTokens(req, accessToken, refreshToken, accessTokenE
147147
/**
148148
* Sign in with Facebook.
149149
*/
150+
151+
FacebookStrategy.prototype.authorizationParams = function () {
152+
return { auth_type: 'rerequest' };
153+
};
154+
150155
passport.use(
151156
new FacebookStrategy(
152157
{
153158
clientID: process.env.FACEBOOK_ID,
154159
clientSecret: process.env.FACEBOOK_SECRET,
155160
callbackURL: `${process.env.BASE_URL}/auth/facebook/callback`,
156161
profileFields: ['name', 'email', 'link', 'locale', 'timezone', 'gender'],
162+
scope: ['public_profile', 'email'],
157163
state: generateState(),
158164
passReqToCallback: true,
159165
},
@@ -197,6 +203,12 @@ passport.use(
197203
});
198204
return done(null, false);
199205
}
206+
if (normalizedEmail === undefined) {
207+
req.flash('errors', {
208+
msg: `Unable to sign in with Facebook. No email address was provided for account creation.`,
209+
});
210+
return done(null, false);
211+
}
200212
const user = new User();
201213
user.email = normalizedEmail;
202214
user.facebook = profile.id;

0 commit comments

Comments
 (0)