fallback sign in flow

This commit is contained in:
2026-03-26 15:05:03 +05:30
parent 625e4709d3
commit fa10677e41
2 changed files with 26 additions and 4 deletions

View File

@@ -10,6 +10,8 @@ import {
onAuthStateChanged,
setPersistence,
signInWithPopup,
signInWithRedirect,
getRedirectResult,
signOut as firebaseSignOut,
type User,
} from 'firebase/auth'
@@ -43,6 +45,7 @@ type AuthContextValue = {
mongoUser: MongoUser | null
loading: boolean
secretKey: Uint8Array | null
authError: string | null
signInWithGoogle: () => Promise<void>
signOut: () => Promise<void>
refreshMongoUser: () => Promise<void>
@@ -56,6 +59,7 @@ export function AuthProvider({ children }: { children: ReactNode }) {
const [mongoUser, setMongoUser] = useState<MongoUser | null>(null)
const [secretKey, setSecretKey] = useState<Uint8Array | null>(null)
const [loading, setLoading] = useState(true)
const [authError, setAuthError] = useState<string | null>(null)
// Initialize encryption keys on login
async function initializeEncryption(authUser: User) {
@@ -151,6 +155,12 @@ export function AuthProvider({ children }: { children: ReactNode }) {
}
useEffect(() => {
// Handle returning from a redirect sign-in (mobile flow)
getRedirectResult(auth).catch((error) => {
console.error('[Auth] Redirect sign-in error:', error)
setAuthError(error instanceof Error ? error.message : 'Sign-in failed')
})
const unsubscribe = onAuthStateChanged(auth, async (u) => {
setUser(u)
if (u) {
@@ -170,8 +180,19 @@ export function AuthProvider({ children }: { children: ReactNode }) {
}, [])
async function signInWithGoogle() {
setAuthError(null)
await setPersistence(auth, browserLocalPersistence)
await signInWithPopup(auth, googleProvider)
try {
await signInWithPopup(auth, googleProvider)
} catch (err: unknown) {
const code = (err as { code?: string })?.code
if (code === 'auth/popup-blocked') {
// Popup was blocked (common on iOS Safari / Android WebViews) — fall back to redirect
await signInWithRedirect(auth, googleProvider)
} else {
throw err
}
}
}
async function refreshMongoUser() {
@@ -205,6 +226,7 @@ export function AuthProvider({ children }: { children: ReactNode }) {
mongoUser,
secretKey,
loading,
authError,
signInWithGoogle,
signOut,
refreshMongoUser,

View File

@@ -5,7 +5,7 @@ import { GoogleSignInButton } from '../components/GoogleSignInButton'
import { TreeAnimation } from '../components/TreeAnimation'
export default function LoginPage() {
const { user, loading, signInWithGoogle } = useAuth()
const { user, loading, signInWithGoogle, authError } = useAuth()
const navigate = useNavigate()
const [signingIn, setSigningIn] = useState(false)
const [error, setError] = useState<string | null>(null)
@@ -63,8 +63,8 @@ export default function LoginPage() {
<div className="lp__actions">
<GoogleSignInButton loading={signingIn} onClick={handleGoogleSignIn} />
<p className="lp__privacy">🔒 End-to-end encrypted. We never read your entries.</p>
{error && (
<p className="lp__error" role="alert">{error}</p>
{(error || authError) && (
<p className="lp__error" role="alert">{error || authError}</p>
)}
</div>
</div>