From 920bf32bdbcc0633cc8a3548845d305b2491e454 Mon Sep 17 00:00:00 2001 From: AlexLopezGomez Date: Sat, 21 Mar 2026 15:11:00 +0100 Subject: [PATCH] =?UTF-8?q?fix:=20revert=20to=20signInWithPopup=20?= =?UTF-8?q?=E2=80=94=20signInWithRedirect=20fails=20due=20to=20browser=20s?= =?UTF-8?q?torage=20partitioning?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit getRedirectResult returned null because modern browsers (Chrome Privacy Sandbox, Safari ITP) partition storage between quorum-be4ac.firebaseapp.com and testquorum.com, so Firebase cannot retrieve the pending redirect state after OAuth completes. signInWithPopup is now safe to use: testquorum.com is in Firebase authorized domains and *.firebaseapp.com is in CSP connectSrc (commit 327ee0d), which was the missing piece causing the original auth/popup-closed-by-user error. Co-Authored-By: Claude Sonnet 4.6 --- frontend/src/components/auth/SocialAuth.jsx | 17 +++++--- frontend/src/context/AuthContext.jsx | 45 ++++++++------------- 2 files changed, 28 insertions(+), 34 deletions(-) diff --git a/frontend/src/components/auth/SocialAuth.jsx b/frontend/src/components/auth/SocialAuth.jsx index 6d6fc1c..a319c07 100644 --- a/frontend/src/components/auth/SocialAuth.jsx +++ b/frontend/src/components/auth/SocialAuth.jsx @@ -17,13 +17,20 @@ const GITHUB_ICON = ( ); export default function SocialAuth() { - const { loginWithProvider, error: authError } = useAuth(); + const { loginWithProvider } = useAuth(); const [loadingProvider, setLoadingProvider] = useState(null); + const [error, setError] = useState(null); async function handleProviderLogin(providerName) { + setError(null); setLoadingProvider(providerName); - await loginWithProvider(providerName); - // Page navigates away on redirect — loading state clears on return + try { + await loginWithProvider(providerName); + } catch (err) { + setError(err.message); + } finally { + setLoadingProvider(null); + } } return ( @@ -34,8 +41,8 @@ export default function SocialAuth() {
- {authError && ( -

{authError}

+ {error && ( +

{error}

)}
diff --git a/frontend/src/context/AuthContext.jsx b/frontend/src/context/AuthContext.jsx index e1b2824..01aeb7d 100644 --- a/frontend/src/context/AuthContext.jsx +++ b/frontend/src/context/AuthContext.jsx @@ -1,5 +1,5 @@ import { createContext, useContext, useReducer, useCallback, useEffect } from 'react'; -import { signInWithRedirect, getRedirectResult, signOut as firebaseSignOut } from 'firebase/auth'; +import { signInWithPopup, signOut as firebaseSignOut } from 'firebase/auth'; import { auth, providers } from '../config/firebase.js'; import { authApi } from '../lib/api'; @@ -34,32 +34,10 @@ export function AuthProvider({ children }) { useEffect(() => { const controller = new AbortController(); - - async function init() { - try { - const result = await getRedirectResult(auth); - if (result) { - const idToken = await result.user.getIdToken(); - const data = await authApi.oauthLogin(idToken); - dispatch({ type: 'AUTH_SUCCESS', payload: data.user }); - return; - } - } catch (err) { - let message = err.message; - if (err.code === 'auth/account-exists-with-different-credential') { - message = 'An account with this email already exists. Try signing in with a different provider.'; - } - dispatch({ type: 'AUTH_ERROR', payload: message }); - return; - } - - authApi - .me(controller.signal) - .then((data) => dispatch({ type: 'AUTH_SUCCESS', payload: data.user })) - .catch(() => dispatch({ type: 'LOGOUT' })); - } - - init(); + authApi + .me(controller.signal) + .then((data) => dispatch({ type: 'AUTH_SUCCESS', payload: data.user })) + .catch(() => dispatch({ type: 'LOGOUT' })); return () => controller.abort(); }, []); @@ -86,9 +64,18 @@ export function AuthProvider({ children }) { const loginWithProvider = useCallback(async (providerName) => { dispatch({ type: 'LOADING' }); try { - await signInWithRedirect(auth, providers[providerName]); + const result = await signInWithPopup(auth, providers[providerName]); + const idToken = await result.user.getIdToken(); + const data = await authApi.oauthLogin(idToken); + dispatch({ type: 'AUTH_SUCCESS', payload: data.user }); } catch (err) { - dispatch({ type: 'AUTH_ERROR', payload: err.message }); + await firebaseSignOut(auth).catch(() => {}); + let message = err.message; + if (err.code === 'auth/account-exists-with-different-credential') { + const other = providerName === 'google' ? 'GitHub' : 'Google'; + message = `An account with this email already exists. Try signing in with ${other} instead.`; + } + dispatch({ type: 'AUTH_ERROR', payload: message }); throw err; } }, []);