fix(auth): login Google retombait sur le callback import (userId null) -> route par purpose vers completeGoogleLogin

This commit is contained in:
2026-09-26 21:30:54 -04:00
parent 2d56bd70e7
commit bb203f405c
+27 -7
View File
@@ -516,6 +516,11 @@ r.get('/oauth/:provider/callback', oauthLimiter, async (req, res) => {
if (!code || !state) return fail('oauth_missing_code_or_state');
const entry = consumeOAuthState(String(state));
if (!entry || entry.provider !== provider) return fail('oauth_invalid_state');
// Le login Google revient ici : buildAuthUrl utilise toujours la redirect URI
// /api/oauth/google/callback (une seule URI à enregistrer côté Google).
if (provider === 'google' && entry.purpose === 'login') {
return completeGoogleLogin(req, res, frontBaseForOAuth(req), entry, String(code));
}
const tokens = await exchangeCode(provider, String(code), req);
if (!tokens?.accessToken) return fail('oauth_token_failed');
let profile = { id: '', displayName: provider, avatarUrl: '' };
@@ -2101,15 +2106,15 @@ r.get('/auth/google/url', loginLimiter, (req, res) => {
}
});
r.get('/auth/google/callback', loginLimiter, async (req, res) => {
const frontBase = frontBaseForOAuth(req);
/**
* Finalise un login Google à partir d'un state `login` déjà consommé :
* échange code → profil → find-or-create → session + cookies → front.
* Partagé par /api/auth/google/callback ET /api/oauth/google/callback
* (buildAuthUrl n'enregistre qu'une seule redirect URI côté Google).
*/
async function completeGoogleLogin(req, res, frontBase, entry, code) {
const fail = (code) => res.redirect(302, `${frontBase}/auth/login?error=${encodeURIComponent(code)}`);
try {
if (req.query?.error) return fail(String(req.query.error_description || req.query.error));
const { code, state } = req.query || {};
if (!code || !state) return fail('google_missing_code_or_state');
const entry = consumeOAuthState(String(state));
if (!entry || entry.provider !== 'google' || entry.purpose !== 'login') return fail('google_invalid_state');
const tokens = await exchangeCode('google', String(code), req);
if (!tokens?.accessToken) return fail('google_token_failed');
const profile = await fetchGoogleProfile(tokens.accessToken);
@@ -2156,6 +2161,21 @@ r.get('/auth/google/callback', loginLimiter, async (req, res) => {
} catch {
return fail('google_login_failed');
}
}
r.get('/auth/google/callback', loginLimiter, async (req, res) => {
const frontBase = frontBaseForOAuth(req);
const fail = (code) => res.redirect(302, `${frontBase}/auth/login?error=${encodeURIComponent(code)}`);
try {
if (req.query?.error) return fail(String(req.query.error_description || req.query.error));
const { code, state } = req.query || {};
if (!code || !state) return fail('google_missing_code_or_state');
const entry = consumeOAuthState(String(state));
if (!entry || entry.provider !== 'google' || entry.purpose !== 'login') return fail('google_invalid_state');
return await completeGoogleLogin(req, res, frontBase, entry, String(code));
} catch {
return fail('google_login_failed');
}
});
r.post('/auth/refresh', async (req, res) => {